GOLANG СОБЕСЕДОВАНИЕ LAMODA НА 300К — Transcript

Техническое собеседование по Go с обсуждением проектов, Kafka, микросервисов и архитектурных решений в Ламода.

Key Takeaways

  • Опыт работы с Go в телекоммуникационной сфере и микросервисной архитектуре.
  • Понимание принципов работы Kafka и её ограничений в гарантии доставки сообщений.
  • Знание преимуществ и недостатков микросервисов с точки зрения масштабируемости и надёжности.
  • Практический подход к решению архитектурных задач и обсуждение реальных кейсов.
  • Важность коммуникации и возможности задавать вопросы в процессе собеседования.

Summary

  • Видео представляет собой техническое собеседование на позицию Golang-разработчика в компании Ламода с зарплатой 300К.
  • Собеседование состоит из трёх частей: обсуждение предыдущих проектов, ответы на технические вопросы и обсуждение тестовых заданий.
  • Кандидат рассказывает о своем опыте работы с ядром МТС, включая разработку компонентов базовых станций на Go и микросервисную архитектуру.
  • Обсуждаются особенности Kafka, включая отказоустойчивость, гарантии доставки и проблемы с дубликатами сообщений.
  • Рассматриваются плюсы и минусы микросервисной архитектуры, её масштабируемость и надёжность.
  • Обсуждаются вопросы распределённых транзакций и взаимодействия микросервисов.
  • Кандидат делится опытом работы с Docker, Kubernetes, gRPC и Kafka в реальных проектах.
  • Ведётся технический диалог с разбором архитектурных паттернов и антипаттернов в системах.
  • Видео содержит практические советы по улучшению кода и архитектуры, а также обсуждение инструментов и технологий.
  • В конце предусмотрена возможность кандидату задать вопросы о компании и процессе работы.

Full Transcript — Download SRT & Markdown

00:01
Speaker A
Привет. Привет. Да, Лена, приветствую. А сегодня проведём техническое собеседование. Оно будет состоять из трёх частей.
00:13
Speaker A
В первом минут 15 говорим о предыдущих проектах, местах работы. А дальше часть пого, то есть, э, походим немножечко, пос попрашиваем вопросам.
00:27
Speaker A
А, и третья часть — это запросики. ПД писать тоже поговорим там про некоторые вещи.
00:37
Speaker A
Предлагаю ещё заключительная часть, когда уже ты нам можешь задавать вопросы про наши компании. О'кей, понял.
00:46
Speaker A
Тогда предлагаю начать. Расскажи, пожалуйста, про предыдущие проекты. Какие, может быть, интересные случаи были, такими стандартными?
00:56
Speaker A
Угу. А, ну проекты у меня, то есть я вот успел поработать в ядре в МТСе, всё на гошке, в ядре, наверное, такой я сам себя слышал. Всё, больше не слышу. В ядре, наверное, самый такой необычный опыт был, потому что там не просто там,
01:12
Speaker A
не знаю, ээнд какой-нибудь там, а там типа базовые станции, короче, мы разрабатывали. Вот как бы в основном, ну, типа я не знаю, ладно, у нас 15 минут, я поподробнее могу рассказать.
01:21
Speaker A
Типа базовая станция, ну, по сути, это типа сервак на Линуксе. Просто и там как бы, если какое-то сетевое взаимодействие происходит между компонентами, то это всё в рамках одного сервака. Вот там много разных компонентов, большинство из них написано на C, но вот один из них, который мы
01:34
Speaker A
писали, он написан на Гошке. И по сути он из себя представлял опишку базовой станции, а, в которую ты можешь обратиться и как-то сконфигурировать базовую станцию, там поворот антенн, а, там что-нибудь, я не знаю, там радиомодуль, там посмотреть все аварии,
01:49
Speaker A
которые на базовой станции есть, там типа и куча вообще там параметров, я даже большей части из них не знаю вообще там страшное название. Вот там типа на гошке не смот Вот удивительно там как бы у нас вот этот наш компонент опишка она
02:02
Speaker A
короче была на микросервисах, но это микросервисная архитектура не назвать, потому что там ну у нас всего полведра было для этого, они не скейлились как бы никак, то есть по сути распределённый монолит просто был. Вот по брокеру сообщения общались там,
02:16
Speaker A
все как бы антипаттерны были соблюдены и паттерны нарушены, потому что там типа а брокер сообщений был НСКУ, ну типа довольно быстро, если на него большую нагрузку не класть, но через него синхронные вызовы тоже производились, поэтому, ну, короче, никакого GRPC там
02:34
Speaker A
ничего не было. Через брокер сообщений синхронно общались. Вот. Угу. М. Ну, там куча всяких технологий было, которые вообще никто никогда не слышал.
02:42
Speaker A
Типа сисрепа, там это хранилище нетконв, там, короче, куча всего такого. Вот. А ещё успел поработать в рамках же ядра, только уже не базовая станция, а система управления базовыми станциями. Это, короче, уже типа вебморда там для операторов, чтобы они там зашли там
02:58
Speaker A
сразу там перезапустили там 10 000 базовых станций там Санкт-Петербурга. Вот что-нибудь такое. Там уже такой популярный стек, там уже, короче, у нас всё в Кубере запускалось, а, ну, в докерконтейнерах, понятное дело. Там уже и JRPC у нас было, вот кавка. Ну,
03:13
Speaker A
суперплотно с кавкой так и до сих пор не поработал. Ну просто типа там кинуть, прочитать.
03:19
Speaker A
Вот. Ну это вот в ядре было. Угу. Вот. Потом в НТС, если что, вы меня останавливаете, просто везде по-разному там прось пропо рассказывать. Вот где-то быстро, где-то не быстро. Вот. Потом вот в МТС пошёл. Ну вот до сих пор тут сижу,
03:34
Speaker A
а тут уже прямо что-то такого супер необычного нету. По сути, ну просто бэкэнд, как бы вот в самом вот стандартном представлении. Вот самый вот обычный стек, типа просто вот даже я не знаю рассказывать нечего. Ну просто типа всё-всё на гошке, всё в
03:54
Speaker A
докерконтейнерах, всё в кубере, кавка, всё GRPC, где хочешь там дис себе поднимаешь, где хочешь там позгрю поднимаешь, что хочешь, короче, делаешь просто. Вот сам стар прямо вот что-то такого необычного нет. Вот. Ну вот сейчас я вот именно в отделе маркетинга,
04:12
Speaker A
то есть там всё, что связано с маркетингом. Вот там всякие промокоды, там скидки, рекламные кампании, вот это вот всё.
04:18
Speaker A
Угу. Вот так. Хорошо, спасибо. Так, я тогда вопросики задаю общие по, ну, техническому стеку, так скажем. А смотри, как думаешь, вот кавка, она отказоустойчивая, за счёт чего? То есть какая есть там особенность в архитектуре?
04:38
Speaker A
Ну, опять же, типа, я вообще не специалист Кавки. Сейчас попробую так прикинуть. Ну, типа, почему она отказоустойчивая? Потому что там, типа, она позирует. Ну, во-первых, она там пишет на диск, короче, там, ну, типа дампы свои. Во-вторых, там можно настроить её
04:51
Speaker A
несколько реплик, ээ, чтобы, короче, она там неполно, блин, такие, конечно, деобсовские демы, я говорю. Вообще с кавкой очень плохо работал.
04:59
Speaker A
Ага. Ну, стандартные темы, там реплики, дампинг, вот это всё, вот это всё. Угу. А про, э, гарантии доставки вот знаешь какие она предоставляет? Э, в рамках, короче, насколько я помню, в рамках одного кластера она нам это обещает, что у нас всё будет, короче, в
05:22
Speaker A
том порядке, что мы отправили. Вот. То есть не будет, ну, короче, порядок доставки будет соблюдён.
05:28
Speaker A
Вот. И то, что типа в целом сообщение будет доставлено. То есть там типа если мы отправили в Кавку, получили ОК, то как бы всё это сообщение не потеряется.
05:35
Speaker A
Вот. Ну и там, соответственно, уже на принимающей стороне мы там можем его как-то заасептить, типа то, что всё, мы его приняли, можно нам больше не пытаться отправить. Угу.
05:46
Speaker A
Вот есть такая штука most, да, гарантия в доставке. Можешь сказать, что она означает? Это монс. Это то, что, ну, мы отправляем сообщение, и оно может быть будет доставлено, а если будет, то не больше, чем один раз. Вот.
06:07
Speaker A
Ага. Али. Ну это типа мы отправляем и оно хотя бы один раз точно будет доставлено.
06:17
Speaker A
А может не один. Вот. А вот если не один раз, то это ну нормально вообще. И ты что предложил сделать, если бы у нас бизнес-логика была бы чувствительна к дубликата?
06:33
Speaker A
Не использовать инструмент, который нам этот листован говорит. Ой, блин, сказал же, что не профессионал в кафке. [смех] Ладно. Так, ну о'кей. То есть мы используем какой-то инструмент, он у нас там типа, ну, обычно, если у нас какая-то такая тема, что у нас там шина
06:49
Speaker A
данных, она, э, может доставить, может не доставить, может доставить несколько раз, то её обычно используют, ну, не как какое-то средство сообщения, а просто там, не знаю, какие-то метрики, там поток данных просто и там метрики типа собираем куда-нибудь складываем. Вот. Но
07:02
Speaker A
если мы чувствительны к этой теме, ну, блин, не знаю, вроде кавка этим не страдает. Вот.
07:10
Speaker A
Не, ну она вот гарантии-то не обеспечивает. Защита от дубликата, да, но я имею в виду вот at least once, он как бы может, э, мы можем наблюдать дубликат.
07:19
Speaker A
Вот. Ну о'кей. Так, тогда такой на вопрос ещё. Как думаешь, вот у микросервисной архитектуры [музыка] какие плюсы и минусы?
07:30
Speaker A
Основно, ну, вообще сейчас уже у нас, ну, практически везде, наверное, микросервис есть, если это не какой-нибудь монолит. Ну, ну, типа, с точки зрения менеджмента это проще, потому что ты можешь как бы, ну, разделять зону ответственности очень так хорошо, типа, на команды, там, на людей.
07:47
Speaker A
Вот с технической части микросервисы у нас, ну, если нормально сделать, это более надёжная система получается, потому что мы можем несколько реплик себе поднять. Если у нас там какая-нибудь реплика падает, у нас есть другие. Если у нас весь реплика сет
08:00
Speaker A
падает, у нас, скорее всего, система не упадёт. Опять же, если там типа нет каких-то там единых точек отказа. Вот.
08:06
Speaker A
Плюс с помощью микросервисов можем как бы довольно масштабные системы строить. И опять же за счёт того, что мы их можем масштабировать. Если у нас там типа а блин, слово забыл. Если у нас стоит вас как короче микросервис, то мы можем
08:19
Speaker A
вообще там без проблем его там скейлить вот и типа в ширину там просто несколько серваков купили и поехали. Вот. То есть с монолитом это, ну, гораздо сложнее было бы сделать. Монолиты тоже, я знаю, там скейлят, но совсем там издевательство.
08:34
Speaker A
Ну вот первое, что было бы пришло. Хорошо. Смотри, вот есть такая штука, как [откашливается] распределённые транзакции. То есть вот, допустим, у нас есть ряд микросервисов, мы хотим выполнить какой-то вот такой процесс, который все эти микросервисы затрагит, да.
08:54
Speaker A
система, то транзакцию мы себе позволить не можем в БД, да, ну, я имею в виду в рамках одного сервиса.
09:02
Speaker A
Как бы ты предложил, то есть слышал какие-то паттерны, которые вот позволяют такие транзакции таки реализовывать?
09:10
Speaker A
Ой, вообще сейчас можно сразу мне минусик ставить за этот вопрос. Насколько я помню, что-то там типа в какой-нибудь файл или в пагр можно писать ну ну короче какие-то шаренные данные и через них как-то синхронизировать вот типа состояние сервисов. Вот.
09:27
Speaker A
Угу. Ну, состояние персо просаги. Начитал ничего. Так, ребята, у вас есть вопросы вот по первой части?
09:43
Speaker A
Ну вот да, у меня вопрос микросервисной архитектуре. Штука вообще ненадёжная. То есть можно какой-то запрос не пройти, а можем повторно начать проходить. Вот как решается проблема, что один и тот же запрос, например, может два раза прийти, ну, из той же системы очереди из
10:07
Speaker A
Ну, ну, обычно, типа, если мы со стороны как бы микросервиса, там нам мы просто предоставляем IP, а там уже кто нам что, как сколько отправит, ну, столько всего мы сделаем, блин.
10:21
Speaker A
Ну, то есть одно сообщений может прийти два раза и ну не хотелось бы два раза повторять.
10:27
Speaker A
Ну тут уже смотря что именно какая бизнес-логика, потому что если нам просто приходит, я не знаю, у нас там какой-нибудь сервис погоды, ну типа понятное дело, ничего такого, что нам там 500 раз один тот же запрос придёт.
10:38
Speaker A
Вот если у нас там какие-то платёжные транзакции, ну понятное дело, тогда там, ну тогда нужно же думать, как это сделать. Обычно там типа на каждую операцию там какой-нибудь Uит ставится, и мы типа смотрим, что мы делали эту операцию или нет. Ну или как-нибудь там
10:51
Speaker A
по запросу хэш считается, смотрим, что мы типа такого делали уже или не делали. Вот. Но тут надо на бизнес-логику не посмотреть, типа, почему нам вдруг плохо, что нам два раза один и тот же запрос пришёл.
11:03
Speaker A
О'кей. Так, тогда предлагаю дальше пойти, да? Ждём тогда к первой части. Андрей, я тебе тогда слово передаю.
11:16
Speaker A
Ага хорошо. Так, я сейчас поделюсь ссылочкой на редактор, где мы будем писать код. А запускать ничего не надо. Будем пока в уме запускать и анализировать.
11:31
Speaker A
Так, скажи, когда откроешь. Please enter your name. Всё зашёл. Ага, отлично. Ну, вопрос такой, что выведет эта программа?
11:49
Speaker A
Так, у нас А она она немножко с подвохом, поэтому будь внимателен и для удобства можно комментарии писать, даже рекомендую.
11:58
Speaker A
Так, ладно. Вот у нас есть слайс 1 2 3. Мы А, ну понятно. Так, ну, короче, у нас есть, мы взяли от этого слайса, сделали ещё один слайс, который только первый элемент хранит. То есть src у нас, ну,
12:14
Speaker A
типа у них как бы базовый массив один, но вот src у него лен один, поэтому в срц только один, как бы видно. Вот мы этот слайс кидаем сюда. Тут он опендится.
12:27
Speaker A
А, ну, короче, да, и в у нас будет 153. Вот. Ну, а src, src он не изменится, потому что тут у нас, когда мы передали функцию, там типа как бы, несмотря на то, что память у нас та же, но сама
12:40
Speaker A
структура вот эта другая, поэтому у нас append и мы сохраним в src уже в другой слайд, который по истечению функции как бы уже всё. Но память мы поменяли. Короче, в СРЦ у нас так и останется один, а в
12:54
Speaker A
будет 153. Вот 153. Ну, давай запустим. Да, да, я оно всё правильно. Ну, это круто, на самом деле. Многие ошибаются здесь. А так, ну тогда там сразу очевидный вопрос задам, который ты явно ответишь. Из чего? Как устроен массив? Ой, как
13:22
Speaker A
устроен слайс? Угу. Ну, это структура, там указатели на память лен и капасть. Вот. Да.
13:31
Speaker A
А как работает? Appent он, короче, если у нас лен меньше, чем капати, тогда он в тот же базовый массив там докидывает ещё элемент и возвращает слайс новый, у которого просто лен один больше. Вот. А если, короче, у нас ну нету уже места,
13:52
Speaker A
то там типа перевыделения памяти происходит. Там мы новый базовый массив ищем, он там на небольших размерах там в два раза, короче, каждый раз больше. А там на больших там уже всякие оптимизации.
14:05
Speaker A
Понятно. А, хорошо. А вот доступ к, собственно, доступ к элементу массива алгоритмическая сложность у нас какая?
14:15
Speaker A
Мм, ну, типа индексация. Ну, от единицы там как бы нам не неважен индекс. Ага. А когда мы добавляем элемент в конец?
14:24
Speaker A
Мм, когда добавля Да. А сейчас, ну, короче, блин, сейчас подумаю, э, когда добавляем, ну, типа, у нас если есть место, то по сути нам неважно там какой длины, тоже от одного. А если пересобираем, то там уже, блин, уже надо
14:44
Speaker A
смотреть, как там вообще локатор Гошки там за такое время он вообще ищет новую память. Но если памяти достаточно, то типа зат одного мы добавляем, потому что типа А всё равно от одного. А, понятно.
14:58
Speaker A
А, хорошо. А как бы ты эту программу исправил, чтобы вот не было этого сайффекта? Ну, потому что здесь вот прикол, что функция по сути меняет. Хотя вроде на первый взгляд не должно как от этого это мейком можно в срц выделить память и
15:18
Speaker A
потом, ну, вот этой встроенной функция копия скопировать туда array. Угу. Отлично. Хорошо. А вот если мы выделили массив, он нам больше не нужен. Как есть какая-нибудь конструкция, чтобы можно было переиспользовать эту же этот же память этого же массива, а не создавать новый,
15:40
Speaker A
не выделять новый? Это же слайс. Слайс. Не, ну, конечно, типа, если он просто у нас останется, если он у нас там в стеке, если мы напишем код, так что у нас остаётся в стеке, или там типа если мы там
15:54
Speaker A
какой-нибудь указатель на него прокинем, что он в кучу попадает. Ну да, типа, ну я не очень понял, типа, ну вот мы создали слайс, там как хочешь эту память используй, типа добавляй, удаляй. Если там хочешь какой-то новый слайс там с
16:05
Speaker A
другим типом данных, ну тогда нет. Типа, насколько я знаю, ну Гошка такого не представляет. Нету там, как в плюсах, там бой звёздочка. Вот. А, ну, хотя есть этони, но, короче, ну, я честный вопрос не очень понял.
16:19
Speaker A
Ладно, хорошо, я согласен. А, Андре, давай давай вот по последнему вопросу тоже немножечко скорректирую. То есть вот смотри, Лен, допустим, у тебя в цикле ты копируешь постоянно слайс что-то, да? Угу. Да. И ты знаешь, что у тебя, э, входящие вот эти вот данные,
16:39
Speaker A
они, ну, какого-то размера, но максимально ты знаешь, что они там допус аргументы мейка там, то, что можно сразу, короче, несколько элементов создать и чтобы он был и и длины, и капаси там типа пять, условно, а можно просто капати выделить, а лен как бы
16:56
Speaker A
ноль. Вот. Ну да, типа предвыделить память можно. Угу. же у меня всё-таки предложение вот то, что вот Андрей спрашивал по поводу то, как исправить эту программу, да, можешь, пожалуйста, написать вот как ты бы хотел это сделать?
17:10
Speaker A
Так, о'кей. Ну, типа исправить это какое тогда у нас вообще, ну, результат должен быть 1 2 3 получается вот.
17:20
Speaker A
Ага. Ага. Ну, о'кей. Так, ну, типа у нас вот srц, мы там типа мейкаем его. Что у нас там? И три. Вот.
17:30
Speaker A
И тут, ой забыл наверное слева дист. Ну, типа, куда мы копируем, а тут откуда? Забыл, короче.
17:41
Speaker A
Ну да только немножечко результат получится не тот, который надо. Давай запустим просто, посмотрим. Знаешь, как получилось? То есть надо, чтобы было, э, src единичка.
17:54
Speaker A
Ну тогда да, понятно. с src типа. Ну, мы скопировали короче туда. Так, ну ладно, сейчас [смех] так нужно, чтобы src1 было. Тут 1 2 3.
18:09
Speaker A
Ну, короче, понятно, 1 2 3. Поэтому мы что-то если с Ну, я просто вот, в принципе, м, ну, типа, ничего можно тогда не делать срце просто и и всё. И просто, ну, ладно, я какие-то ладно.
18:26
Speaker A
Ну вот типа как как и было. То есть мы в целом просто лен уменьшили, типа, и всё.
18:33
Speaker A
Вот. А если вот так сделаем, то А насколько я помню, копия, короче, ну скопирует только первый элемент. Вот это то, что надо или это не то, что так? Сейчас, а скопирую первый элемент.
18:49
Speaker A
Ээ ну вообще у нас тут уже другой базовый массив будет. Вот поэтому типа когда мы тут запендим, то уже в другую, короче, пойдёт память. Поэтому, ну, насколько я понимаю, да, типа, оно заработает.
19:09
Speaker A
Так, тогда давай дальше пойдём. Ага. Ну тогда давайте к следующей задаче перейдём. Так, у нас вот такая а программа.
19:21
Speaker A
А для начала просто расскажи, что она делается, но и потом покритикуй. Так, слайс урлов. Мы идём по урлам, запускаем рутину.
19:37
Speaker A
Урл копируется у нас, так что всё норм. Фенг что-то там. Ерфеч ул. А так, о'кей. R не равно.
19:53
Speaker A
Так, ну что, у нас запускается четыре рутины, каждая из них делает, и потом мы 400 мсекунд ждём, короче, пока они там все принтефы свои сделают.
20:07
Speaker A
Вот. Отлично. А что бы здесь ты предложил улучшить? Да ну, типа вот это та time сп такое себе, типа вейт группы бы повесил.
20:21
Speaker A
Ну давай повесим. Давайте повесим. Так, что она там в синке у нас? Ладно, просто для простоты групп. Ну, типа перед запуском мы там добавляем.
20:42
Speaker A
И вот в гарутинке у нас тут так что-то у меня дам. Вот. Ну и тут all request launcher. Ну и тут вот типа ждём.
20:58
Speaker A
Ой ой ой. Всё забыл. Хорошо. А почему нельзя было ВГС добавить прямо? Да, можно, да, можно было. Можно вот типа, ну так как-то канонично, типа, я не знаю, сразу вот на глаз проще воспринимать, что вот мы прямо перед
21:19
Speaker A
запуском добавляем и ну прямо перед запуском рутини добавляем в Йгруппу и потом сразу же типа ждём. Ну конечно, типа, ну никто не мешает вот здесь вот и там типа лен улс.
21:31
Speaker A
Ага, да, отлично. Нет, я имел в виду верни, как было. А почему нельзя вот добавить, например, на перед дефем? прямо вот на уровне функции, а типа прямо в грутине, да?
21:47
Speaker A
Нет, ну опять же написать-то можно, но в чём прикол? Если у нас мы будем добавлять единички в вей группу прямо в рутине, то что может произойти? Мы за там типа запустим из рутин, они там пока попадут там в своей локальной очереди,
22:02
Speaker A
пока их там машина на ядро пустит, короче, у нас мы уже можем дойти до тридцать восьмой строчки, увидеть, что мы ничего не запустили, и программа завершится. Вот.
22:12
Speaker A
Угу. Хорошо. Отлично. А скажи, в какой последовательности вот эти урелы будут отрошены? У планировщика надо спросить. Ну, для нас случайно вообще.
22:24
Speaker A
А а понятно. Хорошо. А давай, а вот если у нас здесь будет, допустим, не четыре урела, а я не знаю, 100.000 какие-нибудь сложности возможно, да? У нас типа могут закончиться там эти, ну, порты, в принципе, куда мы ходим. Вот. Э-э, да, и в целом, короче,
22:50
Speaker A
насколько я помню, что-то, ой, ну, сейчас вообще пальце в небо, что-то вроде Linux системы, они там типа одновременно до 10.000 соединений там на одном хосте могут держать. Вот. Ну, в любом случае, короче, даже если там, э, не порты, ничего, там, вроде ещё
23:05
Speaker A
дескриптор файловой системы у нас тоже там не бесконечный. Вот. Короче, в любом случае какие-то проблемы могут быть, если мы вот там в одну секунду 100.000 запросов запустим. Вот.
23:14
Speaker A
Ага. Хорошо. А как бы это нужно было решить? Ну, про писать не будем, но давай порассуждаем, [фыркает] да? Ну, типа, как решить? Мы бы могли просто запустить ну типа в общем говоря, нам нужно ограничить количество запускаемых рутин, то есть
23:34
Speaker A
ограничить количество запросов. Вот как мы это могли бы сделать? У нас бы могли быть какие-то рутины, типа там workркер, вот, который просто слушает какой-то канал входящий. Вот. И мы там запускаем сразу там, ну, я не знаю, там, 1.000
23:46
Speaker A
этих воркеров. Вот. И потом в этот канал мы, ну, канал буферизированный, эээ, какой-нибудь, и мы в него просто пишем наши урлы. И, соответственно, они вот так вот будут этими тысячу горутинами там по чуть-чуть обрабатываться.
24:00
Speaker A
Хорошо. А вот ты упомянул планировщик, а можешь чуть подробнее о нём рассказать? Угу. Ну вот, планировщик в Гошке, то есть это вот часть Рантайма, насколько я помню. То есть он управляет как бы гартинами, короче говоря. Вот. То есть,
24:18
Speaker A
ну, я так понимаю, вопрос про именно планировщик Гошки. Да конечно. Да. Вот, то есть модель вот эта вот GMP, у него типа рутина машина процессор, то есть у нас есть сущность это рутины, то есть это какие-то потоки исполнения. У
24:33
Speaker A
нас есть машины там, так называемые, это как бы сущность, которая вот типа сидит на ядре, она там вот может в своей локальной очереди доставать рутину и там кидать её на исполнение. Вот у самих рутин там что-то есть три стейта,
24:47
Speaker A
короче, типа готово к выполнению, выполняется и там типа на паузе. Вот. Ну и соответственно там типа он запускает эти горутины, которые готовы выполняться. Когда там какие-то рутины ставятся на паузу, он их вытесняет, да, там ставит на исполнение другие. Вот. Ну
25:06
Speaker A
там типа ещё можно сказать там про всякие типа стилинг рутин, то, что там типа если там одна машина сильно нагружена, у неё там много рутин в очереди локальной, а вторая там чилит, то вот эта вторая, она там будет брать
25:18
Speaker A
рутинки из локальной очереди первой, чтобы распределить там нагрузку по ядрам. Вот. Угу. А, хорошо. А вот всё-таки гурутина, что такое? Это типа тред операционной системы, как или что? Чем-то отличается?
25:34
Speaker A
Ну да, отличается от треда. Ну вот как бы вот фраза типа легковесный поток. Почему он легковесный? Потому что происходит переключение рутин в рамках одного физического потока. То есть если у нас там какой-нибуд Linux надо переключить, нам там надо, короче, все
25:48
Speaker A
его регистры куда-то запомнить. Там все какие-нибудь процессорные кэши там куда-то запомнить, короче. Потом [откашливается] найти, короче, этот стек этого процесса, там всё это, ой, этого потопка, всё это, короче, куда-нибудь выгрузить, а потом ещё тот, на который мы хотим переключиться, это всё нам вот
26:05
Speaker A
так обратно нужно закинуть. Поэтому это долго. Вот. А переключение рутин происходит в рамках одного физического потока. То есть вот эта как раз машина является этим потоком. Поэтому это типа всё быстро происходит. Вот.
26:17
Speaker A
А а как ты переключишь вообще горутину? Ты же всё равно его переключаешь. не сохраняя стекст, там стоя регистры и прочее.
26:26
Speaker A
Ну я честно горудины руками не переключал. Не знаю, как не я знаю. Никто не переключал руками.
26:32
Speaker A
Делает планировщик просто сказал, что это дорого, потому что нужно пере сохранять регистры, там ещё что-то, найти стек и прочее.
26:40
Speaker A
А разве когда переключаешь рутину, это всего не надо делать? Ну, у нас там типа один поток именно.
26:49
Speaker A
Ну, какая разница? Ты переключаешь кусок кода на процессор, вставишь, он должен выполнить. Как процессор будет знать, что ему нужно выполнить другой кусок код?
26:57
Speaker A
Ну, как там, я не знаю, в процессоре, как это называется. Сейчас, а, те же самые регистры надо переключить. Я свожу вопрос к тому, что то же самое переключение происходит всего этого, сохраняется всё это и всё переключается.
27:10
Speaker A
Но почему-то рутины переключаются быстрее, чем ТД в операционке. Почему? Почему? Ну тогда не знаю, почему они так переключаются.
27:19
Speaker A
О'кей, тогда поехали дальше. А в какой момент вообще происходит переключение между, ну, понятно, что у процессора, допустим, там 16 ядер, не знаю, сколько, а, арутин может быть 1.000. Вот в каки момент происходит переключение исполнению?
27:39
Speaker A
Ну, типа, когда у нас какая-то рутина либо, ну, там какой-нибуд сетевой запрос делает, она там типа переходит в состояние паузы и, соответственно, её типа сменяют. Либо, короче, там с какого-то начиная с какой-то версии Гошки. А у нас если
27:56
Speaker A
какая-то рутина очень долго там сидит на ядре, то её просто в рандомный момент времени типа могут вытеснить и изменить другой. Вот.
28:04
Speaker A
Отлично. Хорошо. А так у нас ещё вопрос. Да, я хотел по этой части ещё буквально пару вопросиков задать по поводу планировщика.
28:17
Speaker A
А, Лёня, вот, допустим, смотрел у нас, а ты говоришь, что когда мы делаем сетевой запрос, да, вот что с м происходит в этот момент?
28:34
Speaker A
привязана к М, да. Вот. И вот сделали сетевой вызов, то есть куда М потом девается.
28:41
Speaker A
Ну, М - это же машина, она типа никуда не девается. Она так и сидит на ядре.
28:46
Speaker A
Вот гарутина типа переходит в состояние паузы потому что она типа залочена на сетевом запросе. Её как бы выкидывают с ядра в локальную очередь. Вот и всё. А потом, когда типа к ней уже придёт ответ, она там типа, я не знаю, переёт в
29:00
Speaker A
какое-нибуд состояние, там типа готова к исполнению, и когда там её очередь наступит, она опять на процессору пойдёт.
29:07
Speaker A
А вот надполер, э, так слышал понятие, не для чего он. Угу. А вот смотри, допустим, когда мы файлик читаем, то есть у нас с м что происходит? То есть в отличие оттего.
29:27
Speaker A
А почему что-то должно происходить? Типа мы же читаем там. Ой, не знаю. От меня, наверное, хотят ответ, который я не знаю.
29:38
Speaker A
Да, смотря, знаешь, я могу немножко по-другому перефразировать. Вот есть ли отличие, когда мы делаем сетевой вызов и сил, который вот, допустим, файл, когда читаем, то есть с м в этом эти этим м мы можем воспользоваться для дальнейшей обработки. Вот, допустим, при сетевом
29:56
Speaker A
вызове и при чтении файла. Ой, не, мне сейчас только гадать. Не знаю, ну, могу типа предположить, но, короче, я не знаю. Ну, типа, когда сетевой у нас вызов, то там, [кашель] [откашливается] ну, типа, в сетевой вызов, если у нас сил, то, блин, я уже
30:13
Speaker A
слабо помню, но насколько я помню, типа какой-то сил, это мы просто, ну, ядро, которое у нас вот выполняло программу, оно типа э вот этот счётчик команд перекидывает на область памяти, где у нас системные команды. То есть, по сути,
30:26
Speaker A
мы всё равно как бы какой-то деятельностью занимаемся. Вот. Там, знаешь, там разница в том, что при сетевом вызове мы трем воспользоваться можем, потому что он не лочится, да?
30:38
Speaker A
Вот. А при сколе тред лочится и как бы мы им воспользоваться уже не можем, пока вот не закончим сист.
30:46
Speaker A
Ну вот, да. Вот. Угу. О'кей. Дари, передануть. Угу. Хорошо. Ну вот, возвращаясь к нашу программку, э у меня такая вот пожелание есть. А, допустим, у нас эти уки медленно отвечают и какие-то могут вообще отстрелить с ошибкой. Так вот, я
31:05
Speaker A
хочу, чтобы если какая-то УЛКО отстрелилась с ошибкой, мы тут же закончили выполнение программы. Вот как бы нам её доработать до это?
31:16
Speaker A
Ну, есть очень удобная штука, которую часто используют в коде, но которая нету в стандартных редакторах вот этих вот.
31:25
Speaker A
Это, короче, рор группа. Вот. И типа у нас бы просто горотинка возвращала ошибку. Вот. И в случае чего мы вот как бы возвращаем ошибку. И там при первой же ошибке сразу все остальные рутины завершаются. Вот.
31:39
Speaker A
Угу. Хорошо. Ээ я думал, а ещё какие варианты есть? Этот вариант классный, да? Ещё варианты есть, короче, тут ну это выглядит всё обычно некрасиво и, короче, тяжело прямо сделать нормально.
31:56
Speaker A
Ну, у нас должен быть вот, допустим, типа у нас там по первой же попавшиеся ошибки, то есть у нас там, ну наверное какой-нибудь там контекст должен быть, который бы отменялся в случае ошибки. Все остальные рутины должны как на этот контекст
32:11
Speaker A
завязаться. То есть мы должны до сетевого запроса проверять, что у нас контекст там типа не отменён ли случайно, там какой-нибудь селект с дефолт секций. Вот. И типа вот мы, ну да, тут в принципе после запроса у нас, ну и после запроса тоже там, чтобы и там
32:26
Speaker A
ничего не вывести. Вот. Но тут такое типа начинается это либо, ну, короче, много способов, либо можно как на какой-нибудь, не знаю, атомик завязаться, там какой-нибудь бул, типа, что у нас там бы была ли ошибка или нет.
32:37
Speaker A
Вот. Плюс ещё саму ошибку, если мы хотим где-то вне этих горутин получить, то там типа в канал её надо писать. Вот. Ну, как бы типа способов много. Вот. Но обычно просто это ер группой делается и всё. Вот.
32:49
Speaker A
Угу. Хорошо. А, ну сделай так, как тебе больше нравится. О'кей. Ну, тут, насколько, короче, в этих редакторах я знаю, тут нету рор группы, потому что это типа не стандартный вот такой пакет, там что-то.
33:02
Speaker A
Ну, ничего страшного, даже если забудешь сигнатуру. Так ну так, э, что-то я я не помню. Ерс, ер.
33:17
Speaker A
Угу. Ну, что-то такое. Короче, я понимаю, что в реальной жизни у тебя едыешь. Так, Group. А, ну и, соответственно, вот здесь вот у нас там типа Group, а [откашливается] там что-то го, я уже не помню. И сюда мы, короче, передаём вот эту вот нашу
33:35
Speaker A
функцию ORL, который вот ошибку возвращает. Вот сюда мы, соответственно, пишем вот это. Вот так. И го. Ну, блин, что это такое? А, и тут, насколько я помню, так го. И тут мы, типа, если у нас ошибка не равно, тогда
34:02
Speaker A
мы типа эту самую ошибку возвращаем, если что. Тут типал. А, ну и типа вот здесь мы, ну, смот смотря, где мы хотим, типа, no lached. И тут типа, если, э, что-то в в ерг группе какая-то ошибка и типа
34:26
Speaker A
тогда вот мы там, я не знаю, там что-нибудь ну ер короче выводим. Вот. Ну не знаю, может написать FMD там print ln.
34:42
Speaker A
Ну и всё там типа завершаем. [фыркает] Ну вот типа того, что что типа такого.
34:48
Speaker A
Угу. Хорошо. Проверить сам не могу, потому что точно не помню все сигнатуры. А, коллеги, всё корректно, вроде.
34:59
Speaker A
Значит, а, а, второй вариант, на который я намекал, через контекст, на самом деле. А, то есть, а можешь вы сказать, что такое контекст вообще?
35:11
Speaker A
Да, ну, контекст, то есть там по сути настройка над канальчиком. Вот, ээ, контекст у нас используется вообще для того, чтобы у нас там типа, ну, обычно как бы оно он должен использоваться для того, чтобы типа у нас там приложение, у него там
35:28
Speaker A
несколько уровней, там у нас разные там какие-то компоненты в приложении, там HTTP сервер, там ещё какой-нибудь сервер, там всякие запросы. И мы с помощью вот этого, ну, наследования контекстов можем его так вот делить на слои и потом ещё какие-то слои там
35:42
Speaker A
выключать. Ну, вот там типа отмены контекста. Вот. Ну и там типа завязываться на него там всё, чтобы ресл шотдаун делать. Вот. Но обычно просто делаеть контекст бэкграунд там в мейне, короче, он везде прокидывается просто и всё.
35:53
Speaker A
А помимо контекст бэкграунда какие ещё бывают? А, ну там с отменой типа вин с значением визулью, там с тайм-аутом есть и с дедлайном.
36:04
Speaker A
Угу. Отлично. А вот безлы что-то такое с одничком стоит. Это зачем? Ну, короче, можно там значение передавать в этом контексте. Это, на самом деле, очень редкий кейс. И вот всегда, когда я с этим сталкивался, лучше было бы просто, ну, не делать
36:19
Speaker A
ничего, ну, типа передавать значение просто аргументом функцию, а не через контекст. Ну, вот можно там типа какой-нибудь логер там в него запихнуть, короче, и получать его. Вот.
36:29
Speaker A
Угу. Хорошо. А, коллеги, есть какие-то ещё вопросы? У меня вопросов нет. У меня есть замечания. Я всё-таки сверился с дока и там сигнатура немножко другая, но это несущественное замечание. Так, чтобы все были в курсе и все заново вспомнили, как
36:48
Speaker A
работает группы. Погнали дальше. Отлично. Пошли дальше. Так, следующая задачка. [фыркает] Вот такой код. Что у нас тут будет выведено? [откашливается][кашель] Так, рид. Как она, как она вообще будет работать?
37:20
Speaker A
Так, о'кей. У нас есть какая-то мапа. А, угу. Так, мы делаем рид. Что тут в цикле? Ага, вирай.
37:32
Speaker A
Ну, запусть рит. И вот пока секунду. вра не запустится, мы будем читать. Потом запустится вра. Ну и, короче, у нас пойдёт, ну, вообще там, насколько я помню, просто с ошибкой программа упадёт там типа concurrent read там to map,
37:48
Speaker A
что-то такое вот. Ну, в любом случае тут мапаы типа не обложена там ни мюксом, ничего, и там писать, читать в неё не очень. Ну, короче, нельзя конкурентно, безопасно. Вот. Но, насколько я помню, тут Гошка прямо отслеживает вот так, в
38:01
Speaker A
таком простом случае мы просто упадём с ошибкой короче прямо сразу. Вот так. Ну там она не всегда отстреливает, короче, отстреливает. Нет, одну секунду мы поживём, вот пока мы просто читаем, потом всё, а потом сразу упам через секунду, да? Ну, короче, там, насколько я помню,
38:18
Speaker A
нужно, чтобы попало вот прямо вот вот вот в по-настоящему, чтобы мы прямо именно в один момент обратились там к мапе, и тогда он типа задетектит, но в целом этого может не произойти. Вот поэтому Ага. А вот если ты подозреваешь, что ты
38:31
Speaker A
такой косяк сделал и можно вот есть какой-то способ точно поймать такую проблемную ситуацию? Мм, ну есть типа флажок там вот этот рейс можем с ним запустить.
38:45
Speaker A
Ага. Да, именно. А если мы возьмём, например, не вот на двадцать пятой строке не не а, а читать пойдём.
38:56
Speaker A
Да. Да. Ну он всё равно, типа, рассматривает мапу как, ну, типа, цельный там объект. Вот поэтому, ну, и памяти. Ну, короче, насколько я понимаю, да, всё равно должны упасть.
39:07
Speaker A
Угу. Ну допустим. Так, хорошо, давай как-нибудь подлечим проблем. Мм, ну, можно типа сингмапой, но обычно не очень всё выглядит. Ну, можно сделать. Ну, по сути, что у нас тут тоже в какой-то глобальной области видимости он должен быть. Там, что там синк у нас
39:31
Speaker A
сиte к Ну хотя, ну можно mex. Ну, тут ладно. RV Mutex. Вот. АX запускаем. Ну так, о'кей. Ну, типа, каждый раз, когда мы что-то хотим прочитать, мы там типа лочимся и так, ну, тут у нас что?
39:56
Speaker A
Чтение, да? Вот получается, мы лочимся на чтение, ну, и разлочимся. А тут у нас запись, поэтому просто лочимся, короче, капитально.
40:13
Speaker A
Вот. Вот. А, хорошо. А вот ты упомянул, что сначала просто, потом решил, что RК. А в чём у них разница? Зачем придумали разновидность какую-то?
40:28
Speaker A
Да ну, короче, у нас, если обычный КС мы используем, то мы просто какие-то секции лочим полностью и нам там неважно чтение, запись, короче, просто лочим. И поэтому у нас, ну, почему вообще MEX придумали? Потому что какие-то умные люди заметили, что мы писать в какие-то
40:47
Speaker A
разделяемые ресурсы без безопасно можем, а читать, ну, конкурентно мы можем. Вот. И поэтому типа зачем нам тогда на чтении всё лочить, если мы можем как бы конкурентно читать всё-таки. Вот поэтому вот типа RVM у нас появился, как он
41:03
Speaker A
работает. То есть мы, когда ло лочимся на чтение, то все там другие рутины, которые придут и возьмут лок на чтение, они как бы тоже смогут его взять и не ну не остановятся. То есть у нас мы будем конкуренты читать. Вот. Но как только
41:19
Speaker A
какая-то горутина придёт, захочет взять лог на запись, то мы подождём, пока все прочитают, и возьмём лог на запись. И вот пока мы будем писать, если кто-то в этот момент захочет прочитать, то он тоже будет ждать, короче, пока мы
41:29
Speaker A
допишем. Вот. Но в итоге у нас типа гораздо быстрее происходит операция чтения. Вот если у нас какой-нибудь кэш, мы там много из него читаем, то вот очень хорошо оптимизирует.
41:43
Speaker A
Угу. Хорошо. А ты ещё упомянул ман. А а что ты так не захотел использовать?
41:49
Speaker A
Может, ну потому что там он вот это эни хранит и, короче, с этим неудобно работать, на самом деле. Вот. Потому что там это нужно постоянно приводить типы. Вот когда там получаешь, ну не круто, не? Ну в данном случае можно было бы этого, ну
42:05
Speaker A
типа и мапа, потому что мы тут ничего не делаем со значениями, как бы, то есть могли бы [фыркает] принтном как бы и вот это писать, оно бы всё выявилось, но типа если там что-то потом нужно было делать с этими данными, это очень
42:16
Speaker A
удобно. Вот. А в каком бы случае ты всё-таки сказал не вот здесь сима синмапа. Хорошо.
42:22
Speaker A
Ой, я что-то, короче, читал вообще, на самом деле, вот не видел ни разу я в проде синмапу, но читал. Зачем оно когда используется там что-то на каких-то значениях или оно что-то там как-то начинает там какой-то кэш свою горячую
42:35
Speaker A
холодную мапу и короче я бы никогда её не использовал. Вот. А понятно. Но на самом деле при очень сильной конкурентности она там она будет эффективнее только при очень сильной конкурентности. Они там заоптимизировали всё. То есть это будет эффективнее, чем
42:51
Speaker A
самому сделать мапы и обложить её. Там за нас умные люди подумали. Так это сделать суперу оптимально.
43:00
Speaker A
Хорошо. А ладно. Вот тут ютексы, син мапы, это всё примитивы синхронизации какие-то ещё знаю, да? Ну вот группа тоже можно считать.
43:11
Speaker A
Вейт группа. Ну атомики. Ну что там у нас ещё? Вотксы, атомики. Ну короче вот. Да.
43:19
Speaker A
Первое, что было пришло. Может ещё какие-то там из пакета син есть. Я помню вот, ну, типа, что у нас там мы вот этот блокода только один раз запустим. Вот. Ну что, что там может ещё есть? Короче, вот говорю, первое, что
43:37
Speaker A
вспомнил. Синматомики, мютексы, вот это син группа. Угу. Всё, больше не вспомни. Но они уже реже используются, я согласен.
43:52
Speaker A
Не, ну блин, тогда не помню. Может, что-то там ещё есть. Я уже. Угу. Ну ладно, хорошо.
44:00
Speaker A
А так, э, коллеги, может ещё вопросы какие-то? У меня нету. Да, у меня один вопросик. Э, понял. Для [откашливается] мапы какие ключи можно использовать?
44:16
Speaker A
А они должны быть это comparable. Вот. Да. Массив можно скать? Хороший вопрос. Ну блин я вот знаю, что там типа какой-нибудь канал мы там или или контекст мы там не можем использовать. Вот массив, блин, ну массивы там, блин,
44:41
Speaker A
я никогда не сравнивал, блин, массивым не доводилось. Но если равно равно между ними работает и и оно типа компилируется, тогда можем Угу. На самом деле, знаешь, ещё канал можно использовать.
44:56
Speaker A
Канал можно сдеть. А ну ну ладно. Угу. Угу. Да, да, это можно дальше. Угу. Хорошо. Так, а вообще можешь рассказать, как мапа устроит капот?
45:13
Speaker A
Может, ковырялся? Смотри. Ну, мапа, ш, типа хэштаблица. Вот у нас там все как бы ключи, которые мы передаём, они там хэшируются. Ну и дальше уже вот это стандартный флоу вот этой хэш-таблицы, то, что типа у нас там есть
45:27
Speaker A
э ну вот хэш-функция, да, через которой мы получаем хэш. Сам хэш - это там типа то, где находится там нужным бакет. В этот бакет мы там, короче, кладём значение. Там в одном бакете что до восьми значений может быть. Если мы там
45:41
Speaker A
больше восьми значений у нас получается, то мы ещё один, короче, бакет уже делаем, и рано или поздно нам придётся делать, ну, типа пересобирать данные.
45:51
Speaker A
Это называется эвакуация данных, чтобы мы в один момент не получили там ООН доступ. Вот.
45:58
Speaker A
Хорошо. Ладно, я уже следующую задачку нарисовал. А скажи, что будет выглядеть? [фыркает] Так канал интовый. Сразу запускаем рутину, и мы в него что-то пишем.
46:17
Speaker A
Time sleep. И закрываем, короче, его. Так, ну о'кей. Теперь что-то записали. Мы подождали, пока там рутина запустится. Она, скорее всего, тут запустится и запишется.
46:28
Speaker A
После чего мы закрываем его, короче, сразу. Вот. Но канал у нас не не буферизированный, типа, поэтому мы его закрыли. Сюда мы даже ничего не выведим тут, потому что он закрытый у нас. А вот этот Forange, он работает, ну, типа до
46:43
Speaker A
того, как канал не будет закрыт. Ну, всё, закрыт канал, но ничего не выйдется у нас.
46:48
Speaker A
То есть просто завершится программа. М, ну да. Угу. Давай я попробую запустить. О паника.
47:08
Speaker A
Тогда объясняю, почему паника. Так ладно. А, блин. Ну, короче, понятно. Ну, потому что мы писали закрытый канал. Я что-то вообще совсем забыл, какой-нибудь фрезеррованный канал там под капотом работают.
47:28
Speaker A
Я почему-то подумал, что типа вот тут вот мы, ну, типа за запишем и всё, короче. А там же, да, как бы буфера нет, поэтому мы тут будем лочиться ждать, а тут он вдруг закроется, и у нас запись закрытый канал. Ну да, паника.
47:41
Speaker A
Да, совершенно верно. А давай как-нибудь поправим. Мм. Так. Ну о'кей. Так. А а что мы хотим получить? Вот единичку писать и и выйти. О'кей.
48:00
Speaker A
Ну да. Да. Где я в этом была? Ну тогда обычно закрываю тот, кто пишет.
48:07
Speaker A
Угу. Тут мы будем закрывать. То есть мы тут запускаем никакие там слипы нам не нужны. И тут там что-нибудь FНТ там print L там channel.
48:19
Speaker A
А вот то есть мы запустим рутину. Тут будем ждать, короче, пока в неё что-то запишут, неё запишут, мы сразу выведем и всё, канал закрывается. Вот. Вот это всё нам не надо.
48:30
Speaker A
Не понял. Давай запустим. А там что? Что-чуть? А, да, ещё раз. Ну вот она вот эта.
48:46
Speaker A
Угу. Отлично. Так, коллеги, есть вопросы по этой задаче? Нет, у меня тоже. Погнали дальше.
49:00
Speaker A
Так а что думаете, что-нибудь по каналам ещё или, например, про интерфейс? Да, давай этот про по каналу вторую задачку.
49:12
Speaker A
Вторую задачу, да. На мер на мер Угу. Давайте так. Вот у нас вот такая вот штука.
49:30
Speaker A
можешь изучить код. Могу пояснить. Да. Ну, то есть здесь формируется два канала. Ну да, сейчас я посмотрю.
49:41
Speaker A
Так рассер господи. Так, so что он принимает? Какую-то функцию, которая что-то о'кей рандомный интему принимает. А канал у нас есть. Мы запускаем рутину, в конце мы этот канал закроем. А и мы, короче, 10 раз в этот канал, который мы, да, мы что-то пишем,
50:08
Speaker A
непонятно, типа запустили вот эти вот продюсеры, короче говоря, вот, которые рандомный инт пишут. Вот. Потом ещё раз запустили, который уже не рандомный пишут, а от нуля до девяти.
50:23
Speaker A
Вот. И потом мы, короче, вот это мёрж. Ну, я так понимаю, да, типа мы должны как бы результаты эти канала смёржить.
50:29
Speaker A
Так, имеется два выходных канала, один выходной, требуется резовать функцию мж, который будет сливать данные выходной и выходный. Ну, понятно, да? Да, именно здесь, да, решим.
50:39
Speaker A
О'кей. Так, ну, а нам типа у нас вот этот аут. Всё, мы его возвращаем.
50:48
Speaker A
Аа так, ну, сейчас прикину, типа. Ну вот мы должны как бы вот по всем каналам идти.
50:54
Speaker A
Мы должны как бы, ну, если мы их мёрджим, можно, конечно, типа - синхронно их типа замёрзжить там без запуска грутин. Вот. Но может типа, ну, это если нам нужно вот, чтоб порядок сохранился. Вот. Если не нужно, чтобы порядок сохранился, можем рутину
51:11
Speaker A
запустить. Нам нужно, чтобы порядок сохранился. Ну, они же в принципе не обидят. Так, ну тогда запускаем рутину, в которой мы будем А в этом, [фыркает] ну, тут о'кейце там, которые мы будем, а, из этого канала, который вот у нас есть, мы из него будем
51:38
Speaker A
читать. И типа вот это значение полученное мы будем писать в out. Вот. А, ну типа так пошли по всем каналам. Мы, короче, запустили грутинки, и мы как бы из этого канала мы читаем из всех и пишем. Когда у нас там типа вот
52:05
Speaker A
этот закроется канал, а как вот здесь вот, то у нас горутинка завершится, а так она будет работать. Ну вот вот типа такого.
52:16
Speaker A
Угу. А хорошо. А выходной канал что получится у нас? Вечно открытым. Ну да, тоже надо закрывать. А ре что ещё раз?
52:28
Speaker A
Да, хотелось бы закрыть. Ага. Ну тогда получается, нам нужно его закрыть, когда мы в него всё запишем. А чтобы ну короче понятно, можно вот такой финт ушами сделать, типа группу, вот эти все гарутинки на группу повесить и ещё одной
52:48
Speaker A
отдельной гартине ждать, пока они все запишут и тогда закрывать ат. Вот. Так. Вот у нас синк.
53:02
Speaker A
Так. Т группа. А вот тут вот вот один. Так, мы запустили рутинку тут сразу.
53:16
Speaker A
Магдан. И вот типа так вот в отдельной рутине мы будем типа ждать, пока мы перестанем вообще что-то в аут писать, и после этого сделаем close out. Вот что сейчас ещё прики у меня почему-то мысль, что типа мы А так ну короче выглядит как-то так. Но
53:49
Speaker A
типа если мы запустим все эти горутины вот эти вот. А ну всё, ну да, всё вот так вот. Вот так вот оно выглядит.
54:00
Speaker A
Угу. Выглядит красиво, коллеги. Есть ли вопросы? А у меня нет вопро. Угу. У меня тоже. Погнали дальше.
54:13
Speaker A
Так, идём быстро. Ну давайте тогда ещё про интерфейсы яки чуть-чуть поговорим, раз что так быстро будет.
54:25
Speaker A
А так. А вот такой код. что выглядит. А, ну это вот это сравнение интерфейса с Нилом main что-тоф, который у нас айче у нас тут типа ничего нет. Возвращаем erorр, который типа нил, но на самом деле мы выведем упс.
54:55
Speaker A
Угу. Да. Ну немножко поясни, почему. А, ну интерфейс, насколько я помню, это вообще типа он состоит из там двух указателей. Один - это на тип данных.
55:04
Speaker A
Второй - это на сами данные, ну, типа на сам объект. И вот когда мы вот вот вот так вот возвращаем его, то тут у нас указатель на тип данных, он определён, потому что это типа my error. Ну и всё.
55:14
Speaker A
И теперь уже интерфейс нел. Вот даже несмотря на то, что именно объект, указатель на объект, но указатель на тип данных нел, поэтому у нас интерфейс уже нел. Угу.
55:25
Speaker A
Совершенно верно. Запускаю. пишет: "Давай как-нибудь поправим функцию F, чтобы она адекватнее. Так нужно ну чтобы внешний кос адекватнее на неё реагировал".
55:40
Speaker A
М. [фыркает] Так. А сейчас, кстати, надо так. Ну вот так вот мы делать не будем. Тут типа, если что, мы ренил и тут, если больше пяти, тогда вот это вот ретюрн.
55:57
Speaker A
Myр. Так вот, Рор имплементирует именно не указатель, а просто типа структура. Вот. Хорошо. Ладно. А вообще про интерфейсы, а для чего они обычно используются? Может быть, что-нибудь там про DeppendCy Injection скажешь?
56:18
Speaker A
Да. Ну, используется вообще для, ну, для полиморфизма, чтобы у нас типа мы там могли писать функции там или обрабатывать данные там без конкретных типов, а там просто, что там есть какие-то определённые методы у нас. Ну, часто используются там вот там типа
56:34
Speaker A
когда там, не знаю, пишем микросервис, там типа не, кстати, вот не понимаю зачем, но всегда, короче, уровень стореджа он всегда вообще обкладывается интерфейсами, хотя там всегда один сториж и типа зачем вот. Ну да, вот типа интерфейс у нас просто, если у структуры
56:46
Speaker A
есть какие-то методы, которые, ну, определены в интерфейсе, то она его типа автоматически имплементирует, и можем как бы её использовать там, где интерфейс используется. Вот про dependency injection не скажу, потому что потому что не знаю там, ну, короче, это вот часть солида. Вот в чём прикол,
57:05
Speaker A
я забыл, короче. Да, не скажу сейчас. Вот ты говоришь, ты не знаешь, почему используются интерфейсы для хранилища?
57:14
Speaker A
Да не, я понимаю, что типа там вдруг мы там перейдём на новое хранилище и так далее.
57:20
Speaker A
Не, ещё ещё какая-то другая причина есть, почему интерфейс используется. Ты тесты сам пишешь в работе? Ну, типа, мокнуть мы можем, да, но, ну, и да, не, конечно, да, мы бывает случаи, когда у нас там какая-то жёсткая зависимость какого-то там куберне клиента, и мы в
57:40
Speaker A
юниттесте не можем, как бы, да, его там типа поднимать. Вот поэтому мы используем интерфейс, чтобы мы могли его мокнуть. Вот. Угу.
57:47
Speaker A
Это, конечно, да, но просто обычно и так можно протестировать, но вот типа интерфейсы везде вот шлёпаются.
57:55
Speaker A
Ну, на самом деле это основная, наверное, причина, почему надо использовать интерфейсы. Это на для юнит-тестов написания, потому что без них код не может существовать юниттестов.
58:06
Speaker A
Согласен. Да. А теста много писал? Да. Да, всякие разные книжные писал. А, а как ты тестировал? Ну, если там завес, например, на слой хранения, ну, на базу данных конкретно или ты поднимал базу данных?
58:23
Speaker A
Не, не поднимал. Ну, типа нет. Ну, короче, обычно вот я понимаю, что интерфейсы там мокоть, да, я имел в виду, что обычно ну, типа, у меня вот на практике я так сталкивался что юнит-тестов-то нету, ну, типа на уровень
58:43
Speaker A
хранилища, но при этом, типа, всё интерфейсами обложено там 10 раз. Вот. А так-то понятное дело, там, типа, если мне там нужно тесты написать, то я уже говорил, да, то, что там на на интерфейсы переходим. Вот.
58:56
Speaker A
А приходилось сталкиваться с какой-нибудь, например, с чистой архитектурой или гексагональней? Нет, нет. Ну, скорее всего, с ней сталкивался, но я об этом не знаю.
59:05
Speaker A
А многослойная? Ну нет, тут я в этих терминах я плаваю, ну много ну типа только если гадать, ну, типа несколько слоёв там у нас то, что там, ну да, да, да.
59:18
Speaker A
Уровень апи, там бизнес-логика, там стож. А можно сказать вот что это за слай, да?
59:24
Speaker A
Ты всё правильно сказал. Ну вот терапия, бизнеслобистож, да. Ну типа самые такие вот большие мазки разделения приложения на слои. Это вот, как я сказал, AP тоже бизнес-логика, что это такое. То есть уровень i - это всё, что вот, ну торчит
59:41
Speaker A
на на наружу. Это, короче, там типа и JRPC, HTTP там и брокеры. То есть то, как с нашим вообще сервисом работать.
59:48
Speaker A
Вот. То есть какую функциональность мы представляем наружу. Вот второй слой - это вот уже бизнес-логика. Это то, что вызывается, ну, с слоем IP и то, что уже пользуется слоем стореджа. То есть мы какие-то данные перекладываем, мы какие-то данные получаем и обратно на
60:07
Speaker A
слой AP как бы возвращаем. Он уже там типа клиента возвращает. Вот. Ну и уровень стореджа - это там, собственно, хранение данных там типа, да, там положить удалить.
60:17
Speaker A
Угу. Хорошо. А ещё про интерфейсы. Вот есть интерфейс, который, а, который ты, по-моему, назвал какни, да?
60:25
Speaker A
Угу. А для чего нужен? Да. Ну, any - это типа вот то то самое вот звёздочка, то есть это всё подходит.
60:33
Speaker A
Для чего нужен? Ну, вот у нас, например, какой-нибудь printlнn, мы хотим уметь всё э принтить на экран. Вот поэтому типа, ну, any у него нету никаких методов, поэтому всё имплементирует.
60:46
Speaker A
Вот, типа, всё подходит туда. Угу. А вот прилетела нам какая-то Эни. Угу. Мы хотим всё-таки над ним и методы. То есть мы предполагаем, что там какой-то тип под ним скрыт. Ээ методы у него есть.
61:02
Speaker A
Как мы тогда, да, насколько я помню, вот типа есть такая тема T type switch, то есть типа как switch, только мы можем вот интерфейс привести к как конкретному типу и посмотреть как бы, что там за тип. Вот. Да, совершенно верно. А ещё
61:16
Speaker A
кроме Type Switch, кроме Switch какая есть концерт? Да, можно, блин, вот не помню, вроде через рефлект как-то. Ну то, что можем то тоже типа конкретному типу попробовать привести и там типа второй флажок этот о'кей. То, что это тот тип
61:32
Speaker A
или не тот тип. Ну, через рефлекс совершенно согласен. Это, наверное, третий даже способ, блин. Да ну, больше, наверное, не назову. Такое редкая тема. Короче, за забыл, что там вообще.
61:45
Speaker A
Угу. Хорошо. Так, ну что, коллеги, ещё вопросы есть? Или можем перейти вообще к базе?
61:56
Speaker A
Я думаю, можно пойти дальше. Ага. Отлично. Ну тогда передаю эстафету Саше. Саша, ты микрофон выключил?
62:36
Speaker A
Да, сорян. Так, да, я вставил две таблички. Первая табличка - это корзина, вторая - это купатель.
62:49
Speaker A
Вот они между собой связаны по custer ID колонке. И, собственно говоря, корзина - это то, что пользователь добавил в процессе покупки.
63:00
Speaker A
Вот. И нужно написать запрос, который уводит всех пользователей. колонку ID и email и все элементы в корзине в одном в одной в одном списке.
63:16
Speaker A
Ну, типа вывести пользователя и типа его как бы сейчас по корзины country custom. А, ну о'кей. Ну, типа вывести всех пользователей с их корзинами, как бы, да. Вот я написал, ну, как бы формулировку да.
63:33
Speaker A
Угу. Так, что там? А, ну и типа сразу можем там что у нас там join public cards он custмер idвно public cards ээ customer ID. Вот.
64:06
Speaker A
Угу. О'кей. Так, а вот, э, ты использовал, да? А вот можешь сказать, какой это тип джойна?
64:14
Speaker A
Инер инер. А как он работает? Ну, он находит все пересечения, которые я тут задаю, и выводит только те строки, где вот он, собственно, на, ну, нашёл эти пересечения.
64:27
Speaker A
Угу. Допустим, смотри, если нам надо было вывести всех пользователей, да, которых в корзине ничего нет, ну тогда left join, да?
64:34
Speaker A
Угу. А какие типа джоинов ещё знаешь? Ну есть, да, вот inner join, вот это left right и full join, насколько помню.
64:47
Speaker A
Угу. А full как работает? Full outin. Угу. Ну, full - это типа вот у нас есть left, есть rightin. Это он типа и и left, короче, типа и из левой таблицы докидывает там строки, которых не нашлось на пересечении, а потом ещё и с
65:03
Speaker A
правой тоже докидывает. Угу. Смотри, вот если я здесь через запятую напишу вот так вот, это какой тип джойна будет?
65:18
Speaker A
Ой, это, ну, это вот типа iner joint будет, но насколько я помню, он там Ну да, ну, короче, это inner join. А вот, допустим, если я вот это вот уберу, да, то есть это как уже будет работать.
65:33
Speaker A
А так ну типа блин блин, не помню тут, может, что указать надо. Короче, выглядит так, как будто он это будет full jin. Вот. Но вот так я очень давно не писал. О, не уверен, что он вообще запустится на
65:53
Speaker A
самом деле. Ну, типа, мы тут все как бы Ну да, по просто короче не знаю, только гадать если не скажу.
66:00
Speaker A
Угу. А тогда ещё такой вопрос. Вот, допустим, нам надо вывести только теры, э, у которых, ну, брошены, ну, не брошенная корзина, а, допустим, у нас ошибка, да, в наше нашей таблице, что появились записи в таблице карт, у которых нет
66:17
Speaker A
пользователей поставить. Угу. Как бы ты посоветовал бы вывести какие записи? А нет пользователя, типа он там нал. Ну то то же самое, что было, только ещё добавить и customer ID not.
66:37
Speaker A
Угу. Угу. Так, а давай тогда поговорим про индексы. Какие какие индекс ты сам использовал?
66:50
Speaker A
И вот для ускорения, допустим, запроса. А, ну, в данном случае по кост номер один, например, мы хотим целый запрос, да? То есть, ну, какой тип индексов ты предложил использовать?
67:03
Speaker A
Угу. Так, ну, индексы, ну, что я чаще всего использовал вот этот стандартный B3. Всю жизнь думал, что это Binary 3.
67:11
Speaker A
Оказалось, что это баланс 3. Вот. А, ну, есть у нас там ш индексы, там джин индексы, типа для полнотекстового поиска. Ну, я говорю, это я часто супер не использовал. Ну, в основном это вот этот B3 индекс. Вот. А как он работает?
67:27
Speaker A
То есть типа там все данные он разбивает там в виде дерева, в ноде. А ключ это что за данные? А значение это типа на каких страницах памяти они лежат. Вот за счёт этого типа мы можем не перебирать тупо по всеки уже там заранее знать, где
67:42
Speaker A
что лежит. Вот. А если у нас вот такой запрос типа, да, как как я понял, вот такой.
67:50
Speaker A
И мы хотим, ну вот тут вот у нас типа сравнение происходит. Customer ID. Так индекс индекс.
68:02
Speaker A
Так, ну, типа, что нам мешает просто на колонку кастомера окинуть индекс и всё? Угу.
68:09
Speaker A
А вот какой тип вопрос заложил? Да, B3 и всё. Ну, типа, есть вот швидекс, который у нас для сравнений, но, насколько я помню, он даже в сравнениях типа медленнее, чем B3.
68:21
Speaker A
Вот. Ну, короче, я бы B3 навесил, потому что нам хотя бы, блин, custмер 1 больше меньше, мы вряд ли будем сравнивать, да?
68:27
Speaker A
B3 бы, если честно, повесил и всё. Вот. О'кей. Так, а какие у них вот минусы у индексов?
68:36
Speaker A
Да, ну у нас когда таблица там обновляется, то индекс у нас пересобирается, потому что нам нужно типа, ну, новые данные как бы там перераспределить в графе в дереве. Вот.
68:48
Speaker A
А если у нас таблица часто обновляется, то мы слишком часто будем пересобирать индекс и, ну, можем навредить только.
68:55
Speaker A
Угу. Допустим, вот у нас есть большая-большая таблица, да, и мы новый индекс по колонке добавляем.
69:07
Speaker A
Какие проблемы могут быть в продакшены? Это у тебя табличка, там даны да? Вот. И ты на колонку вешаешь индекс.
69:25
Speaker A
Ну, кроме того, что я назвал, что типа вот она апдейтится. Что ещё может быть-то? Ну, вообще, ну, типа индексы много весят. Мы там можем в внезапно всю память скушать индексом.
69:39
Speaker A
А когда вот ты индекс навешиваешь, там под капотом табли с табличкой, что происходит вообще? Я дал, ну, то есть мы к ней доступ иметь будем на момент на момент навешивания индекса.
69:53
Speaker A
Сразу скажу, точно не знаю. Ну, типа, логично предположить, что она залочится вот на время содания индекса. Угу.
69:59
Speaker A
А есть какие-то есть какой-то способ всё-таки этого избежать? То есть альтернативный способ создания индекса на колонку, да, на большой таблице, чтобы не очень таблицу?
70:14
Speaker A
Мм, не знаю. Угу. Так сейчас. О'кей. Так, давай тогда ко второй. То есть таблицы те же самые, то есть условие как бы примерно такое же и структура таблиц такая же, но формулировка она немножечко другая. Вот задача, э, нам нужно вывести топ-10 клиентов
70:43
Speaker A
по количеству товаров в корзину. То есть имеется в виду, вот нам не важно какой товар, да, разви нам важно понимать, сколько всего мы добавили товаров, неважно каких.
70:56
Speaker A
Так, топ-10 клиентов по количеству элементов в корзине. Ну, типа у нас вот есть таблица, то есть мы хотим Ага, понятно. Ну, короче, как я понял, типа, нужно сделать запрос, сгруппировать по Customer ID там, ну, типа сложить амаountут и отсортировать в
71:21
Speaker A
обратном порядке взять вот этот лимиit 10. Вот. Давай на Ну, клиентов ещё хотим. Понятно. Там publics, там типа join public customer он public cards равно public cards. А customer ID public customer ID.
71:56
Speaker A
А так после этого мы хотим сгруппировать карс. А, ну кастомира оди. А так и типа суммы маунт сум. Блин, давно я на скле не писал.
72:25
Speaker A
Так, суммы маount, а там дискндин и типа custмер idя сумма отди там лимит 10 а и тут, короче, мы просто звёздочку не можем вывести. Мы группировой постой.
72:44
Speaker A
М [фыркает] как-то, короче, надо вывести, ну, типа саму кастоме не можем. Так, нужно ещё имеil этого пользователя вывести.
73:02
Speaker A
А, ну, блин, я забыл, короче, будет он ругаться или нет, если я просто выведу имеil, но если будет, то так. Ой, customer ID. Ой, на email.
73:18
Speaker A
Вот. Ну, если будет, короче, тут ругаться, что там что-то там типа мы не сгруппировали по этому полю, то можно вот тут вот вот так вот через запятую ещё его добавить. Вот.
73:28
Speaker A
Угу. Угу. Ага. Да. Так, а вот если, допустим, у тебя есть, ну, то есть задача такая, выясть всех клиентов, независимо, есть ли у них там в корзине что-нибудь или м твой запрос, он как бы удовлетворяет этих потребности.
73:53
Speaker A
А, ну типа имеется в виду, если у нас типа я не очень понял вопрос, типа, если у нас меньше десяти, да? Ну, смотри, вот, допустим, у одного ноль, да? ничего не добавлял.
74:04
Speaker A
Табличка кастомера есть, корзы ничего не добавлял, а у второго что-то есть, да? То есть получается вот этот запрос, он выведет только одного человека, да, у которого что-то есть.
74:19
Speaker A
Ну, типа, если его в принципе нету вот в этой таблице, да, то его не выведется.
74:23
Speaker A
Угу. Угу. Ну, типа, опять же, можем, что по publicт вот уже join customer, тогда у нас типа подсоединятся кастомеры, даже которых не будет в этой таблице.
74:38
Speaker A
А может, ну как бы вместо райта что может как взять? Райд, допустим, мы не хотим, да?
74:50
Speaker A
Так. Ну вот на этом моменте мы уже типа теряем всех пользователей, которых нету в вот в этой таблице. Вот. А ээ, [смех] блин, что не это?
75:13
Speaker A
Смотри ты получается карте присоединяешь кастомер, да? Может быть, тебя эта формулировка наведёт на определённые мысли, что что-то может по-другому как-то попробовать.
75:31
Speaker A
То есть в левая таблица от карс. Угу. Да. Правая кастомера. Да. Да. А что, если мы левой таблицей сделаем кастомеры?
75:41
Speaker A
Ну, если мы просто типа их поменяем, ничего не изменится, потому что у нас inner joint. Мы можем её сделать слева и сделать, ну, left. Ну, ага, ну да, вот я это имел в виду, что ну да.
75:52
Speaker A
Угу. Угу. Так, смотри, допустим, если у нас у двоих кастомеров будет одинаковое количество, суммы да?
76:02
Speaker A
Угу. Как они, в каком порядке они расположатся на выхоте? Ну, [откашливается] может быть, как-то этот порядок будет зависеть от, ну, типа порядка добавления в таблицу изначально, там, что типа мы заджойним там. Ну, короче, для нас это, я бы просто сказал,
76:20
Speaker A
ну, типа случайный порядок. Не будем же мы там в прот смотреть там, что где, на какой Угу.
76:26
Speaker A
строчке у нас запись. Вот. А, а если попросили по порядку вывесть, то, ну, смотря какому порядку, типа по какому полю хотим сортировать.
76:36
Speaker A
Угу. О'кей. Так, а вот что, если ещё дополнительные условия добавить в эту задачу, нам, допустим, нужно получить только тех кастомеров, у которых в корзине больше статого.
76:51
Speaker A
Ага. А, ну, типа, у нас вот группы можем типа так вот ээ сумount больше 100. Вот.
77:06
Speaker A
Угу. Так м смотря допустим если мы навесили индекс, то есть вот знаешь, что такое стольный индексы, да? Типа когда один индекс сразу на несколько столбцов.
77:25
Speaker A
Угу. Там какие есть вот, э, правила, когда этот индекс будет использоваться? Мм да. Ой, там, короче, честно подзабыл, там какое-то выпендрёжное правило, что там типа все столбцы, которые на равно, они будут использоваться и первый, который на какое-то неравенство там на больше,
77:47
Speaker A
меньше, а все, которые правее, не будут. Ну там, короче, что-то какая-то такие танцы с бубном.
77:53
Speaker A
Угу. Допустим, вот у нас индекс мы навесили на колонку, допустим, customer ID, да, а country и там SKU, да, какие-то три колонки.
78:11
Speaker A
Угу. Вот, допустим, если мы берём, то есть в запросе не будет участвовать там customer ID, да, то будет ли индекс у нас использоваться?
78:23
Speaker A
Ну, он при сравнении используется. Ну, скорее всего, он типа вот и на джойне тоже. А, ну составной.
78:32
Speaker A
Вот так вот. Потом есть, да, например, такой индекс. И в запросе у нас не нет фильтрации по customer ID. А этот индекс будет использоваться?
78:47
Speaker A
Не помню. Ну, вроде нет. Но не знаю, короче. Угу. А если не знаешь, то как бы ты мог это гипотезу проверить?
78:53
Speaker A
Ну как, загуглил бы в интернете, в каком порядке? Вот. А по факту, ну да, интернет, если включили, ну на на деле можно там через вот этот вот Xplain посмотреть вот, ну Xin Analyse и там посмотрим, что вообще используется, не используется.
79:08
Speaker A
Угу. А вот, допустим, у нас есть индекс по колонке да? А всегда ли он будет применяться? Лки какое может какая характеристика используется при анализе вот применения лиц?
79:26
Speaker A
У нас составной индекс или какой? Нет, просто вот на кантри мы это что-то повесили индекс, да?
79:32
Speaker A
Угу. Думали, что нам это как-то ускорит запрос. Вот. Но типа всегда ли будет применяться индекс по это, ну, по этой колонке?
79:53
Speaker A
Ну, то есть чем руководствуется планировщик запросов, да, когда как бы, ну, строит план запроса и анализирует вот надо ли воспринимать или не Ну ладно, вопрос, наверное, по с подвохом. Я опять скажу, что я не знаю.
80:11
Speaker A
Ну, типа, я бы предположил, что типа, блин, ну мы индекс повесили, как бы всё, он типа должен использоваться, но есть такая формировка вопроса, короче, наверное, он не всегда используется, но не знаю.
80:23
Speaker A
Угу. А вот слышал такую штуку, как селективность. А, ну, ну, планировщик, он же не смотрит там селективный, неселективный, насколько я знаю. Он типа просто будет использовать уже на, ну, как я насколько знаю, и уже как бы наша задача там типа
80:37
Speaker A
понять вообще селективная вот эта колонка или нет, чтобы там на гендер там не кинуть индекс там.
80:43
Speaker A
То есть ты хочешь сказать, что у тебя вот ты навесил индекс и он вообще не смотрит на статистику никакую, да, использование там?
80:50
Speaker A
Я я не знаю. Нет, я не утверждаю. Ну ага. Ага. Так, ребята, у вас есть вопросы вот по первым двум вот этим задачам?
81:02
Speaker A
по первом двум задачам вопросов у меня нет. [откашливается] Может быть, просто вопрос, если сталкивался. Вот если я в запросе в этом хочу ещё в каждой строчке вывести список сюже у каждого позра, как бы это можно было сделать.
81:20
Speaker A
Мм, так, ну, сейчас я попробую посмотреть, как это вообще должно выглядеть. А, ну типа СКУ прямо в строге, например, там через Забеду или ещё как бы.
81:32
Speaker A
Угу. Да. Ну, короче, насколько я помню, если вот мы хотим что-то ещё сюда добавить, нам нужно поэтому, ну, сгруппировать ещё просто и всё по скюшкам. Вот. Но, блин, не знаю. Всё, я уже, короче, я поплыл. [фыркает] Ээ хотим вывести. Ну, это уже не совсем
81:51
Speaker A
стандартная скореная штука, но всгреси. Блин, я не знаю, если если какой-то вопрос на там стандартные вот эти встроенные функции, тогда точно не отвечу.
82:01
Speaker A
Угу. Не сталкивался, да? Угу. Ну ладно, хорошо. А ты же проре Аг, да? Ну да. Или про Джейсон, в общем, про какие-то агрегаты с ареями, джейсонами и с конкретина встреч.
82:19
Speaker A
любит такое. Угу. Так, наверное, что такое может вопрос. Не применял ли ты common table expression?
82:35
Speaker A
Нет. Угу. Так, тогда у нас покелю вот последняя сейчас будет задачка и может быть если останется время, там ещё какие-то вопросики задаём.
82:50
Speaker A
Так, сейчас я скину задачку. Так вот, у нас есть такая простая табличка, отражающая как бы какое-то приложение, где есть пользователи, у них есть баланс, да, ну, будем называть банковское приложение.
83:12
Speaker A
Вот есть функция на псевдокоде написана, которая делает списание денег с баланса пользователя. Вот. Да, предположим, что у нас реально какая-то вот такая среда, да, то есть когда у нас конкурентное выполнение, да, то есть это прямо продакш система.
83:31
Speaker A
И чтобы вот ты здесь, посмотрев на эту функцию, да, ну, мог бы заметить какие-то проблемы, да, вот можешь поста посмотреть подумать рассказать.
83:44
Speaker A
Мм так ну о'кей. Так, функция что-то там. Ага. Select баланс USER. Ну, типа, у нас тут вот это всё не атомарно происходит, поэтому поэтому, короче, все вытекающие отсюда, ну, типа вот селект мы тут получили баланс, а тут update set банс баланс
84:13
Speaker A
минус оди. Ну вот тут вот мы получили баланс, а там в какой-нибу, ну не знаю, вообще другом потоке исполнения мы его обновили, но тут мы его всё ещё считаем старым. Вот поэтому неправильное будут списания у нас происходить.
84:26
Speaker A
Угу. О'кей. Это да, одна проблема. Вот прямо вот может раскидать. Вот какая ситуация может получиться, как это на балансе отразится.
84:38
Speaker A
Ну типа так. Ну, сейчас вот это баунт, типа, столько-то списать. О'кей. Ну, типа мы там пользователь, э, хотя он один и тотже, ну, короче, типа два раза что-то купит. Вот. Но при этом пишется у него только какая-нибудь одна вот эта
84:59
Speaker A
вот из покупок вот. А вторая просто потеряется. Ну, это как этот, что там? Ой, забыл, как аномалия по-умному называется. Там какой-нибудь LT update, что-нибудь такое. Вот то, что типа, ну да мы спишем один раз, там минус 50 руб.,
85:14
Speaker A
минус 100 руб., но тут вот будет баланс старый там, поэтому там только что-нибудь одно из этого останется. Вот.
85:21
Speaker A
Угу. Может ли отрицательный баланс получиться? Мм, так, баланс минус маут. Ну да, может. А, ну или стоп. Ну, а вот мы получили баланс. Тут мы считаем, что он типа у нас о'кей, но в этот момент кто-то нам сделал меньше. Но
85:42
Speaker A
тут-то мы всё ещё старый баланс, как бы думаем, что он, ну, про старый, поэтому значение типа в два раза не спишется.
85:49
Speaker A
Вот. То есть отрицательно не может быть баланс. Да. Ну, сейчас, сейчас скажу. Так, баланс, э, блин. уже сложно, конечно, смотреть на на это всё.
86:12
Speaker A
Ну, короче, ну, блин, ну да, ну, скорее всего, может. Я просто уже не вижу, я уже всё, уже у меня всё замылено всё уже.
86:20
Speaker A
Ну давай просто не спеша, да, вот просто подумаем, как может получиться вот в такой программе отрицательный баланс. У меня маленькое предложение. Может быть, дадим перерывчик на несколько минут, потому что действительно тяжело. Да не, давайте, не, можно не торопиться, да, можешь
86:38
Speaker A
подумать. Мы как бы этот не торопим ни в коем случае. Вот ты подумай просто, посмотри вот там, ну, как вообще вот отрицательный баланс в такой программе получиться.
86:51
Speaker A
Так, мы получили его раз у нас больше равно нуля. А, ну это, блин, я тупанул. Я думал, что вот тут вот баланс, который там используется, он как как-то от переменной зависит, но от переменной не зависит.
87:07
Speaker A
Вот поэтому типа Ну да, мы вот там в двух параллельных там тредах взяли баланс. В двух параллельных тредах он там был больше, ну, типа нам хватало денег.
87:18
Speaker A
Угу. А и мы типа два раза списали. И вот тут он два раза спишется, да, и будет типа меньше нуля. Ну, у нас там, условно говоря, типа 60 руб. Там, типа, у нас там две покупки по 50 руб. И они такие:
87:28
Speaker A
"Ну да, больше нуля и два раза спишется по 50 руб. Да, отлично". Так, а вот может ещё какие-то вот так если повнимательнее посмотреть, да? Да.
87:38
Speaker A
О'кей. Проблема с, э, гонками она существует, но есть ещё как минимум две, может, я могу сказать даже две проблемы да?
87:49
Speaker A
Угу. Ну, то, что у нас типа деньги во флотах, да? Да. Ещё одна проблема. О'кей. А вот ты бы какой вариант предложил, если бы всё-таки по-правильному делать с деньгами?
88:01
Speaker A
Угу. Ну, тут смотря, что у нас за система, типа, если у нас там она рассчитана на то, что мы будем там и в рублях, и в долларах, короче, там ещё в чём-нибудь ещё оперировать, там вообще какие-то надо сложные уже структуры
88:12
Speaker A
писать. Но если у нас, допустим, просто рубли, ну там самое простое - это в копейках считать. Вот.
88:18
Speaker A
Угу. Угу. Так. И вот ещё одна проблемка. А, может быть, ты её тоже заметишь.
88:28
Speaker A
Так, о'кей. Ещё одна зритель. Да, она не связана вот не с ни с гонками, да, вот ни с деньгами. То есть это, да, ты подсветил правильно, но есть ещё одна такая проблема. Это уже, можно сказать, такая логическая ошибка, да.
88:45
Speaker A
М, ну, ну не знаю, типа мы не если у нас вот это условие не выполняется, то мы ничего не возвращаем. Ну не знаю.
88:57
Speaker A
А, ну типа это ок. То считаем у нас псевдокод, да, что мы типа ничего не сделали, да, как бы, ну, типа там функция, которая ничего не делает и ничего не знает. Вот.
89:11
Speaker A
А смотри, вот на седьмой строчке тебя ничего там не смущает, может быть, в самом запросе.
89:21
Speaker A
М, ну типа user у Но мы типа user ID не передаём. Balance, ну, user ID как бы, да, не передаём. Угу. Да. То есть мы меняем баланс у всех пользователей. Получается, что неправильно.
89:41
Speaker A
О'кей. Так, а вот смотри, допустим, мы хотим написать код нормально, то какие варианты могутся?
89:50
Speaker A
Угу. Ну, транзакцию использовать. Ага. Так, ну, а можешь накидать вот где какие участки, в каких участках ты бы вот транзакцию вызставил?
90:04
Speaker A
Так, ну, типа, что-то там хотим сделать с балансом. Не, ну можно, конечно, было бы повесить, но смотри, кс не защитит нас этих проблем.
90:21
Speaker A
Ну, ну если у нас единственное взаимодействие с баской в этой функции, то да, если не единственное, то нет, не защитит.
90:30
Speaker A
Допустим, у тебя несколько инстансов сервиса, да, которые не не защитит, да. Так, ну, транзакция там что-нибуд там типа там TX, я уже забыл, что там старт или как она бегин.
90:43
Speaker A
Тут нет, тут на самом деле можно писать вот как бы просто тем же псевдокодом можно писать, который тамгу.
90:52
Speaker A
Так, ну [музыка] [колокольчик] I sorry. Так, а значит, начали транзакцию. Ну, блин, конечно, вот так вот написал и всё. Что, что там комит? А, ну хотя она, блин, ну там зависит от вообще ой от драйвера, что мы используем, поэтому
91:13
Speaker A
ладно, да, давайте никак не за Ну, допустим, у нас здесь позгре, да? Вот так. Ну, всё, тут начинаем транзакцию, короче, всё. А, по сути, так, получили баланс.
91:29
Speaker A
Так, получили баланс. Смотрим, что если у нас больше их на нуля. Так, нам типа теперь нужно её либо закоммитить, либо ролбекнуть. А-а, по сути, сект мы, ну, нам не надо ролбекать, только если апдейт. Но тут есть какая-то ошибка произойдёт, он его типа сам
91:45
Speaker A
ролбекнет но Ну да, ну типа тут как будто довольно просто, ну, типа всё начали там и закомитили её, типа всё.
91:59
Speaker A
Ну, тут понятно, да, мы можем ещё сюда попасть поэтому exк. Так, ну я не знаю, я что-нибудь како вал бы тут запомнил, потом типа закомитил там ретурнувал, что-нибудь такое.
92:15
Speaker A
Угу. О'кей. Смотря, эта проблема решится [фыркает] с проблемой тут. Ну давай просто сосредоточимся на проблеме конкурента вот этого, да, изменения баланса.
92:31
Speaker A
То есть вот она уйдёт благодаря вот этому решению. Ну типа смотря какой уровень изоляции мы повесим. Вот.
92:46
Speaker A
Ну вот при дефолтном уровне изоляции. Вот какой у нас духовной, кстати, угре read committed. Вот. То есть мы будем видеть не ну типа при дефолтном нет, как бы а ну или короче при предефолтном мы в этих транзакциях типа возьмём изначально
93:06
Speaker A
вот у нас вот баланс он будет, короче, одинаковый. Ну, допустим, там две покупки у нас. О, господи. Э-э, ну тут вот как раз, да, мы типа сможем два раза купить, короче, вот.
93:24
Speaker A
Угу. Угу. А чего вот как думаешь, не хватает? Ты, ну, в принципе, правильно сказал, но давай ещё какой-то вариант рассмотрим.
93:33
Speaker A
Ну, всё-таки не меняя уровень изоляции. Вот что что бы ещё может было накинуть, да, чтобы это заработало.
93:46
Speaker A
Так, не меняю уровень изоляции. Что ещё можно было бы накинуть, чтобы это заработало? Мм, [фыркает] блин, не знаю.
93:58
Speaker A
Давай я тебя наведу просто попалом. Допустим, смотри, мы же понимаем, да, что у нас мы не хотим, чтобы с одного и того же пользователя э так вот небезопасно, да? То есть ты там предлагал кс вот может быть в базе есть
94:13
Speaker A
аналогичные примитивы синхронизации какие-то которым мог бы воспользоваться то есть нам именно так как мы шарим бдшку да нам, ну мы не можем использовать, да, мы можем использовать блокировки, да, да, есть там типа вот это вот мы можем там select for update взять, вот
94:35
Speaker A
взять блокировку. А не помнишь вот как его, где его надо написать? Ой, [фыркает] не не помню, не сюжется последишника.
94:50
Speaker A
Так, о'кей. Да, это один из вариантов. То есть вот если мы навесим блокировку, то мы защитим таким образом. То есть у нас две транзакции, они будут блокироваться друг другом, да? Кто первый взял блокировка, та первее.
95:05
Speaker A
Вот. А есть ещё как это? Вот, допустим, да, там предложил с уровнем изоляции. Давай вначале, знаешь, поговорим, а какие есть уровни изоляции, какие проблемы они вообще, для чего они нужны.
95:18
Speaker A
Так, ну вот у нас есть в пагре read committed, э, repeatable read и seralizable.
95:25
Speaker A
Угу. Вот типа read committed у нас то есть мы увидим изменения там совершённо другой транзакции только после того, как она там их закоммитит. Вот repeatable read это мы там, насколько я помню, в начале делается типа слепок там таблицы,
95:43
Speaker A
там сnпшот, вот мы в рамках него работаем и там типа другие транзакции комит, не комитят, мы там всё равно не увидим.
95:50
Speaker A
Вот. Ну и сейзаable - это вообще там, насколько я помню, просто последовательно как бы все э транзакции выполняются.
95:58
Speaker A
Ага. Смотри, вот rep repeatable read какая вообще вот то есть ну зачем мы вообще сделали? То есть какая есть проблема, которая иногда возникают, которые надо как-то решить? Как вот она называется?
96:12
Speaker A
Есть такое слово аномалия, да? Ну да, дада. Так, ну, типа, вот что у нас там может наримите происходить? То есть мы Ой, блин, все эти названия аномалии ещё.
96:27
Speaker A
Так, ну что, смотри, название название уровня изоляции оно как бы повторяющееся чтение да переводится получается.
96:36
Speaker A
Угу. Значит, оно, наверное, решает какую-то проблему, которая обратно называется [фыркает] чтение. Но а, ну давай я скажу неповторяющееся.
96:53
Speaker A
Вот естьпалия, которая называется non repeatable read. И вот может просто на примере, э, как она, как она проявляется.
97:03
Speaker A
Ну вот сейчас, да, пытаюсь вспомнить вообще. Так, non read. Так, ну, получается пять проблемы. Вот как раз наверно на комитет у нас встречается. А, то есть, смотри, вот, допустим, мы на седьмой строчке баланс прочитали, да? А у нас уровень изоляции repeatable ээ
97:24
Speaker A
read committered, да? То есть вот у нас здесь есть проблема неповторяющаяся в чате. Ой, короче, я уже всё.
97:35
Speaker A
Да, давайте минусиг там поставим просто и всё. Ну, ну смотри, если мы в двух транзакциях два раза баланс прочитаем, точнее, если в этой транзакции мы ещё раз баланс прочитаем и кто-то в середине его поменял, мы разное видим значение
97:52
Speaker A
или одно и то же прид комитет. Так, ну тут-то мы его типа в переменную запоминаем один раз, поэтому кто там что его поменяет у нас? Ну, допустим, смотри, вот мы ещё раз хотим его как-то прочитать да?
98:07
Speaker A
Угу. Вот. Вот между двумя этими, э, вызваны у нас будет одинаковое значение, точнее. Ну нет, нет. То есть если кто-то закоммитит, у нас типа readмит, то у нас другое значение будет. Вот, да. Вот как раз пример неповторяющей сения, что в рамках одной транзакции мы
98:26
Speaker A
видим разное значения, когда кто-то меняет, да, вот это полан. У вот тогда repeatл бурит он, ну вот как эта ситуация исправит?
98:34
Speaker A
Ну как вот я сказал, у нас там типа сnпшот делается, и поэтому мы как бы, несмотря на то, что там кто-то что-то поменял, мы всё равно одни и те же данные будем получать.
98:45
Speaker A
Угу. Смотри, а вот как вот, ну, может, я понимаю, что это может быть ты как бы не сталкивался прямо до такой степени, но вот как вот readт работает, то есть он на блокировках реализован или на каких-то других механизмах?
99:07
Speaker A
Ну нет, типа если блокировка, это уже какой-то сериалайбл, как будто вот. Ну, сериала был использовать блокировку.
99:19
Speaker A
Я не знаю сейчас, что он под капотом использует. Вот. Угу. Угу. Так, о'кей. Да. Ну, то есть вот смотри, мы получается вот эту проблему изначальную да мы можем, получается, так ты говоришь ещё уровень изоляции решили, да? Какой бы предложил
99:38
Speaker A
уровень изоляции использовать? Так, ну, readт комитет разобрались, что тут будет аномалия. Вот, типа, если мы возьмём Repeatable read, то в целом, а у нас вот вот этот вот lстдет может случиться, насколько я помню, типа то, что мы в одной транзакции там списали
99:59
Speaker A
баланс, ну, а во второй-то у нас вот этот сNпшот, поэтому мы не увидим это списание. Вот. И и опять, короче, придётся типа, ну, одно списание потеряется. Вот. Ну, на самом деле, давайте просто поправлю, что Lost Update тут, ну, Lost update от
100:19
Speaker A
потери на обновление, дефолтный уровень изоляции комита, то он защищает от рос апдейтов. То есть вот такая вот Тамарная, на самом деле, вот этомарны происходит.
100:30
Speaker A
То есть у тебя делается блокировка на момент изменения, да? То есть у тебя не может так быть, что кто-то перепишет э результат другой транзакции.
100:42
Speaker A
Ну да. Ну я про этот про Repitable read. А repatable read он типа Да, он на самом деле в Постгресе его можно здесь применять.
100:55
Speaker A
Потому что он практически работает как сериал на других птэшках. То есть у него больше уровня гарантии, так скажем. Вот.
101:04
Speaker A
И а что будет? Смотри, вот, допустим, если мы repeatable readт поставили, да, и кто-то у нас поменял баланс, когда вот это вот, да, я и гово Ну ладно, я уже может типа ну не прав, но вот на насколько я помню, вот у нас есть
101:22
Speaker A
repeatable read. Э мы делаем в начале сnпшот в каждой транзакции. Вот мы в одной транзакции сделали апдейт, а во второй транзакции типа этого апдейта мы не увидим. Вот сделаем ещё раз апдейт. И типа поэтому у нас только один раз
101:37
Speaker A
баланс пишется, но может какие-то блокировки, короче, я не знаю, типа возможно, если мы там в двух транзакциях захотим там одно и то же один и тот же столбес поменять, то они там типа залочатся, короче, и не дадут.
101:51
Speaker A
Хз. Угу. О'кей. Так, а вот смотри, может быть, э что я тебе скажу, что есть ещё один вариант, как это всё поправить. Это используй один запрос, то как бы ты переписал вот это всё, э, партянку на один запрос?
102:19
Speaker A
Ой, короче, не знаю, опять сейчас только что-то предполагать придётся. Возможно, это всё можно типа вот в одну функцию сQэльную запихнуть. Я не знаю, какая как они там исполняются. Возможно, там типа, ну, атомарно, типа, она будет выполняться вся функция. Вот. Но
102:35
Speaker A
как-то прямо именно в один запрос, типа SQэльный, ээ, с апдейтом, я не знаю, как это вообще можно сделать или нет, чтобы сразу селек апдейт был.
102:44
Speaker A
Давай подумаю. Просто смотри, у нас тут три три операции, да? То есть первое - это мы берём текущий баланс, проявляем он какое-то, ну, условие, да, что должно быть больше нуле.
102:57
Speaker A
Потом мы делаем апдейт и потом должны возвратить текущий баланс, который у нас получился. Вот.
103:07
Speaker A
Как думаешь, вот как вот эти вот три вещи, да, можно просто в один апдейт загнуть?
103:14
Speaker A
Ну типа апдейт. Вот там у такого-то юзера баланс там больше амаountу. Угу. Да. Вот. Ну и как-то вернуть ещё надо, блин.
103:26
Speaker A
Я не знаю, апдейт у нас, ну, там можно там есть такая штука в разгре, что мы можем вернуть текущее значение баланса, получается.
103:38
Speaker A
Вот. Ну, о'кей, да, тогда писать не будем. В целом, правильно сказал, что можно в апдейте проверить вот это вот условие, да, баланс, ну, как бы ама туда тоже передать, да.
103:56
Speaker A
Вот качестве параметра User ID тоже не забыть, да, вот это вот условие. Ну и, собственно, как бы это вот эта первая строчка нам вообще не нужна, потому что мы просто томарно меняем баланс, да, за счёт дефолтного уровня изоляции редкомита. У нас здесь
104:17
Speaker A
никаких вот этих проблем не будет. Потерянных обновлений не будет. Значит, как бы отрицательного баланса у нас быть не может, потому что у нас всё это исполняется получается.
104:32
Speaker A
Окей. Так, ребята, у вас есть вопросы по вот это задочке? Вопросов может было, было, было бы, но у нас уже время подоспело. А 15 минут осталось.
104:46
Speaker A
Давай так далее. Они твои вопросы к нам, пожалуйста, какие хочешь задавать. Ну давай. Да, у нас Рлан тут такая практика. Мы, ну не, не везде и так, но мы рассказываем обычно про компанию, да?
105:00
Speaker A
А, о'кей. Есть вопросы есть. У всех по-разному, на самом деле. Все по-разному. Собе окей.
105:06
Speaker A
Угу. Да, спасибо, что, ну, как бы всё, мне кажется, было здорово, на самом деле.
105:13
Speaker A
Угу. [фыркает] Тогда мы расскажем про, э, компанию, как у нас устроена команда, как вообще разработка ведётся.
105:21
Speaker A
инструменты. А, то есть у нас как бы много команд, которые работают над своей как бы областью, да, будем называть это доменом. То есть, например, домен заказов, домен там лояльности, да, домен прайга, поиска. Вот. И их, ну, на самом деле,
105:41
Speaker A
больше самые такие основные. Вот. То есть команда она состоит как минимум из бэкэнта разработчиков, тестировщика.
105:50
Speaker A
их количество может зависеть от, э, сложности, ну, как бы области вот это знания, да. Вот есть продакт менеджер, который отвечает за развитие этого направления.
106:04
Speaker A
Он обычно у нас квартальное планирование используется. Мы раз квартал ставим для себя цели. Они называется objective results. То есть у нас есть много какой-то бэклок, да, продуктовых фич, которые мы должны в квартал попробовать подсократить в количество и загнать вот в рамки 3х месяцев, да? То
106:28
Speaker A
есть мы отрезаем всё, что считаем, что можно отложить. Берём вот то, что прямо хотим сейчас взять. Оцениваем это приблизительно, да, до начала квартала.
106:41
Speaker A
Потом, когда мы начинается с кварталов, мы вот эти фичи уже более детально декомпозируем. У нас задача помещаем в квок.
106:50
Speaker A
А, ну и, соответственно, потом это эти задачи распределяются там к разработчикам. У нас нет такого жёсткого, допустим, привязки к комбану или там терфолом каким-нибудь, да, то есть отжайло. То есть зависит от команды, какой стиль, так сказать, управления, да,
107:11
Speaker A
больше подходит команде. Вот. Ну, чаще, мне кажется, используется каба. То есть у нас есть вот эти задачный квартал, да, они постепенно помещаются в бэклог по мере, так сказать, разгребания, да, вот этого бклога. Вот. И закрепляется за какими-то разработчиками.
107:32
Speaker A
Вот. Обычно разработка происходит в стандартной схеме, то есть создаётся фича ветка. Мы для вообще тасктрекинга используем.
107:41
Speaker A
Для хранения кода у нас пользуется bitтbket. Но мы находимся в процессе переезда на Gitlab.
107:51
Speaker A
Вот, э, как бы, ну, фичеветка, допустим, всё, разработчик завершил разработку, тестировщик проверил задачу, а дальше у нас есть Kubernet Cluster, который все наши сервисы крутятся.
108:07
Speaker A
Мы делаем релиз с помощью CCD, она называется бамбу. Это решение тоже от разработчика Джира.
108:17
Speaker A
А мы также, скорее всего, в ближайшее время перейдём на Gitlab. У нас будет единая как бы, ну, CSD основан GL.
108:29
Speaker A
А, ну, собственно, делаем релиз. Катит, катим всё это на продакшн. Смотрим обязательно метрики после релиза. То есть у нас есть прометаус, графана, есть система алертов. То есть, если у нас вдруг какая-то проблема, то мы можем этот релиз сразу же откатить.
108:52
Speaker A
Вот. А, ну вот в целом есть кратко вот именно как мы ведём разработку, так, наверное, ещё коснусь немножко инструментария. То есть у нас, э, ну, в большей степени это гозык разработки.
109:07
Speaker A
Иногда бы встречается, э, ПХП и Питон, их всё меньше и меньше становится. То есть это то есть мы активно стараемся го использовать. Ну, то есть новые сервисы, да, это прямо стандартно, это только го.
109:24
Speaker A
Вот в качестве бдшки у нас обычно по сгре, а то есть есть, ну там дис для каширования.
109:36
Speaker A
Ну вот, допустим, я сам работал в команде поиска, у нас используется Search. Это тоже довольно-таки непопулярное, ну остальное компании решение. То есть именно в плане поиска он, так применяется.
109:49
Speaker A
Вот у нас есть своя свои внутренние инструменты разработчиков. А первый - это, ну, в общем, у нас на самом деле по большей части микросервиса общаются между собой по HTP, не по JPC.
110:06
Speaker A
А, да, возможно, мы в какой-то момент будем там переходить на JPC. Просто пока прямо супер такой необходимости в этом нет.
110:16
Speaker A
Вот поэтому у нас большая часть взаимодействия, она на HCP. Вот кавка тоже активно используется для аведрай какого-то взаимодействия, да? То есть мы на нём на самом деле не строим RPC, да, на карте. Это прямо я не видел примеров,
110:38
Speaker A
где это было по То есть это чисто как э ивент, ну там соурный, да, какой-нибудь такие вещи.
110:46
Speaker A
То есть у нас есть своя шина общая, да, в которой микросервисы как подписываются на эти события, да, и могут, соответственно, их как-то по-своему обрабатывать.
110:57
Speaker A
Э вот, э, тул, вот, про который я начал говорить, он нужен для того, чтобы вот у нас есть у каждого сервиса swager спецификация, то есть у нас стандарт - это использование swager. То есть мы описываем как бы айпишку.
111:13
Speaker A
Вот. то нам нужно как раз загенерить из неё код. Мы не хотим это руками писать.
111:19
Speaker A
И для этого у нас есть код генератор, который позволяет взять вот эту спекул в ямле, да, и на основе неё сгенерить, а ДТО, это дататрансферочка слой, да, вот так получается код сервера и код клиента. Можем также через него
111:36
Speaker A
сгенерить. Вот этот тул он закрытый, то есть его нет внесорсе. Он также активно сейчас трансформируется. Возможно, мы перейдём на открытое решение, то есть для генерации.
111:52
Speaker A
Вот пока это, ну, как бета такая версия, да, то есть что текущий как бы вот этот генератор, он также остаётся, когда мы его активно используем.
112:02
Speaker A
Также у нас есть генератор структуры микросервиса более play, то есть темплейт какой-то, да, мы сами руками не пишем для новых сервисов. Мы запускаем вот эту штуку, она нам генерит код, э, и мы уже там бизнес-лойку начинаем навать.
112:21
Speaker A
А, и у нас ещё есть также фреймворк для тестирования. То есть помимо юнит-тестов разработчики и тестировщики по большей степени тестировщики, они пишут функциональные тесты. Это когда микросервис он, а мы тестируем его контракт. То есть вот у нас есть
112:39
Speaker A
какая-то ручка, да, point. И нам важно понимать, что вот этот контракт, он соблюдён, то есть мы на него подаём какой-то запрос, а, и он должен ответить ожидаемо. Все внешние зависимости, они макируются. То есть внешний сервис, он предоставляется для него мок.
112:58
Speaker A
То есть мы как бы заранее готовим какой-то ответ, да, который вот на этот запрос он нам отдаст.
113:03
Speaker A
Угу. Вот бдшка тода поднимается как бы рядом, да, на неё накатываются какие-то тестовые данные, текстуры. То есть мы можем проверить даже, что в базе будет храниться после того, как наш наша вот эта логика отработает.
113:18
Speaker A
Вот такой специальный тул, он есть нахабела мода, называется гоной. Ну вот я, наверное, на этом остановлюсь, да. Вот это основной как бы основной всё сказать. Может быть, у тебя есть какие-то вопросы?
113:36
Speaker A
Блин, ну круто про тестирование вообще, конечно, редко слышал, что там кто-то что-то больше юнитов пишет. Вот. А тут, как я понял, функциональны, типа, я их называю, типа интеграционные, когда там запускаешь микросервис, там какую-нибудь пдшку. Блин, круто, круто.
113:49
Speaker A
Вот. А-э, вопросы. Да, в целом так подробно всё рассказано. Мм, да нет, наверное, на самом деле, типа, всё понятно. Вот, типа, если какие-то прямо супервопросы будут, если вдруг я там до финалки дойду, там уже я что-нибудь и поспраши. Вот так.
114:07
Speaker A
Ну, вероятность это очень высокая, да, что я советую, да, подготовиться за какие-то вопросы, которые даже неудобные вопросы, которые ты хотел задать, да, можно задать представителям команды.
114:21
Speaker A
Вот на этом тогда предлагаю закончить. Спасибо ещё разви, что уделял время. Да, вам спасибо. Спасибо за время, было классно. Пока.
114:31
Speaker A
Да, хорошего дня.
Topics:GolangсобеседованиемикросервисыKafkaархитектураMTSDockerKubernetesgRPCразработка

Frequently Asked Questions

Что обсуждается в видео?

Видео представляет собой техническое собеседование на позицию Golang-разработчика с обсуждением опыта, технологий и архитектурных решений.

Какие технологии упоминаются в собеседовании?

В разговоре упоминаются Go, Kafka, микросервисы, Docker, Kubernetes, gRPC и другие инструменты, используемые в современных проектах.

Какие темы затрагиваются по Kafka?

Обсуждаются отказоустойчивость Kafka, гарантии доставки сообщений, проблема дубликатов и подходы к их обработке в бизнес-логике.

Get More with the Söz AI App

Transcribe recordings, audio files, and YouTube videos — with AI summaries, speaker detection, and unlimited transcriptions.

Or transcribe another YouTube video here →