Вступление
00:00:00Каналы - это ключевая особенность, которая делает языки программирования привлекательными для разработчиков. Наряду с такими конструкциями, как goroutines, они позволяют относительно легко писать корректный код. Несмотря на их частое использование в практических приложениях, многие неправильно понимают, как работают внутренние каналы, часто приписывая их какой-то магии. На самом деле каналы - это простые и обоснованные концепции, за которыми не стоит никаких мистических элементов. Они также служат отличным предметом изучения благодаря различным компромиссам и оптимизации, используемым в их дизайне.
Какие свойства каналов интересно изучить?
00:00:38Понимание свойств каналов имеет решающее значение для разработчиков. Каналы обеспечивают потокобезопасность, позволяя нескольким подпрограммам работать одновременно, не требуя блокировок или мьютексов. Они хранят элементы и следуют семантике FIFO (Первым вошел, первым вышел), облегчая передачу данных между подпрограммами по назначению. Кроме того, каналы могут блокировать выполнение программы, пытающейся выполнить чтение из пустого канала, до тех пор, пока другая программа не предоставит необходимые данные.
Проектирование каналов
00:01:22Представьте себя инженером Google, которому поручено разработать каналы связи. Цель состоит в том, чтобы создать эффективную систему, в которой сообщения можно было бы беспрепятственно отправлять и получать в рамках одного канала. Это предполагает решение таких задач, как масштабируемость, надежность и обеспечение минимальной задержки при сохранении высокой производительности.
В какой области памяти хранятся каналы?
00:01:32Каналы хранятся в кучной памяти, потому что они должны быть разделены между подпрограммами, что обеспечивает взаимодействие. Куча - единственная подходящая область памяти для этой цели, поскольку она позволяет динамически распределять и совместно использовать данные в разных контекстах выполнения. Понимание концепции кучи имеет решающее значение для понимания многих аспектов программирования.
Структура канала
00:02:00Понимание структуры и параметров канала Канал структурирован с использованием различных параметров, которые определяют его функциональность. Ключевые атрибуты включают "учетную запись" для определения количества элементов буфера, "сайт" для определения размеров буфера и "buff", который ссылается на фактический буфер. Параметр "clause", указывающий на статус закрытия, интригующе использует 32 бита вместо одного из-за архитектурных ограничений в процессорах, требующих выполнения атомарных операций без блокировки каналов. Дополнительные элементы, такие как связанные списки ("recipe"), индексы ячеек ("x ice", "x v") и мьютексы, обеспечивают эффективную обработку данных.
Каналы как указатели, представляющие сложные структуры Суть канала заключается в том, что он является указателем, ссылающимся на сложную структуру, содержащую все эти поля: от буферов до механизмов синхронизации, таких как мьютексы. Каждый компонент играет определенную роль — будь то управление очередями чтения/записи или обеспечение потокобезопасного доступа с помощью систем блокировки - для обеспечения бесперебойной работы в различных архитектурах процессоров.
Реализация свойств: goroutine-safe и FIFO
00:04:08Для реализации горутина безопасности и FIFO семантика, необходимы: буфер, двух индексов (х и Х), и мьютекс замок только четыре ключевых элемента. Обеспечение безопасности потоков требуется использование мьютекса для эффективного управления параллельным доступом. Для поддержания порядка FIFO важно использовать циклическую очередь в качестве буфера, поскольку она эффективно обрабатывает последовательное хранение данных.
Как работают буфер канала и mutex
00:05:04Механизм циклического буферизации в канальных операциях Механизм циклического буферизации объясняется через роли индексов отправителя и получателя, которые изначально указывают на ноль. Когда данные записываются в канал, они занимают ячейку, указанную индексом отправки, который затем увеличивается, указывая на следующую позицию. Этот процесс повторяется до тех пор, пока не будут заполнены все ячейки; на этом этапе индексы обнуляются для повторного использования, если позволяют условия (например, пустые ячейки). Во время операций чтения поиск данных выполняется по аналогичной логике с независимым перемещением получаемого индекса.
Эффективность за счет создания Круговой очереди Круговая очередь устраняет такие недостатки, как смещение элементов влево при добавлении новых после достижения емкости. Вместо дорогостоящих операций по перемещению, которые освобождают пространство на одном конце и последовательно заполняют другой с нуля, данные могут просто перемещаться по кругу, используя доступные исходные позиции, которые были ранее очищены во время чтения или записи, независимо управляемых с помощью соответствующих указателей.
Передача данных в канал
00:07:18В канале передачи данных отправитель пытается отправить информацию, в то время как считывающее устройство извлекает ее. Если отправитель приходит первым, его поток блокируется до тех пор, пока не произойдет синхронизация. Данные копируются в очередь внутри канала, гарантируя, что обе стороны имеют независимые копии этих данных, что позволяет избежать конфликтов, если только не передаются ссылочные типы. После обработки блокировки взаимного исключения (мьютексы) снимаются для других операций.
Получение данных из канала
00:08:21Процесс включает в себя использование считывателя или приемника для ожидания входящих данных. Как только данные становятся доступны, они подвергаются идентичной процедуре: во-первых, мьютекс блокирует доступ; во-вторых, данные копируются из очереди и передаются.
Переполнение буфера
00:08:38Когда отправитель начинает передавать данные, он постепенно заполняет буфер. Как только буфер заполнится, любые дальнейшие попытки записать дополнительные данные завершатся неудачей, что приведет к приостановке работы отправителя. Этот механизм гарантирует, что каналы смогут эффективно управлять потоком данных, останавливая операции при достижении пределов пропускной способности.
Как устроен планировщик (Scheduler)
00:09:05Планировщики управляют ограниченными системными потоками для оптимизации использования ресурсов. Программы не выполняют подпрограммы в режиме реального параллелизма; вместо этого они полагаются на потоки операционной системы с ограничениями. Для максимальной эффективности планировщики динамически переключают контексты между задачами, чтобы ни один поток не оставался незанятым и все операции выполнялись эффективно.
Как поставить горутину на паузу
00:10:14Когда программа-отправитель не может поместить данные в очередь, она запускает функцию, отвечающую за отправку данных по каналам. Эта функция вызывает "go park", которая напрямую взаимодействует с планировщиком, чтобы изменить состояние этой конкретной программы и отсоединить ее поток. Таким образом, это освобождает ресурсы, сохраняя при этом другие потоки доступными для выполнения.
Как разбудить горутину: очередь спящих горутин - sendq
00:10:56Механизм приостановки и пробуждения подпрограмм Чтобы приостановить выполнение программы, она помещается в очередь отправки, связанную с соответствующим каналом. У каждого канала есть параметр "sendq", который ссылается на структуру, управляющую этой очередью, в виде связанного списка. Элементы в этом списке представляют спящие подпрограммы, а также данные, которые они пытаются передать, или ссылки на память для операций приема. Такая настройка гарантирует, что при необходимости эти приостановленные подпрограммы могут быть эффективно активированы.
Структура и функциональность очереди отправки Ядро очереди отправки состоит из узлов, содержащих два ключевых параметра: один представляет саму процедуру ожидания, а другой содержит либо данные передачи, либо ссылку на память для задач приема. Эти узлы организованы в рамках связанного списка, управляемого "sendq". Несмотря на кажущуюся сложность из-за множества задействованных структур, сосредоточение внимания на их взаимодействиях проясняет, как приостановленные процедуры ожидают активации, пока их не запустят соответствующие считыватели.
Чтение из переполненного канала
00:13:49Извлечение данных из очереди в порядке FIFO Когда данные считываются из переполненного канала, это происходит по принципу "Первый вошел - первый вышел" (FIFO). Получатель извлекает элемент, на который указывают определенные параметры, и после считывания перемещает указатель вправо. Этот процесс гарантирует, что последующие чтения будут нацелены на новые элементы последовательно в пределах доступных буферных ячеек.
Эффективное управление буфером с помощью спящих процедур Спящая программа просыпается, когда в буфере остается место для ее данных. Оптимизация происходит по мере того, как получатели обрабатывают проснувшиеся программы, проверяя очереди на ожидающие отправки и помещая свои элементы в буферы, если они найдены. Каждая операция записи расширяет указатели, обеспечивая упорядоченное размещение будущих записей при сохранении эффективного управления очередями.
Пробуждение спящей горутины Sender
00:15:57Процесс начинается с того, что получатель вызывает функцию, которая изменяет состояние спящей программы на "работоспособную", указывая на готовность к выполнению. Это не означает немедленных действий со стороны отправителя, но помещает ее в очередь, ожидающую планирования и доступных потоков. Оптимизация гарантирует, что действия в спящих программах выполняются только один раз, что позволяет избежать повторной блокировки мьютекса, что повышает эффективность. Каналы становятся доступными сразу после завершения получателями своих задач, не дожидаясь дальнейших действий планировщиков или отправителей.
Чтение из пустого канала
00:17:43Когда считывающее устройство обращается к пустому каналу, оно не может извлечь данные и запускает функцию "парковка". Ведущий пользователь переходит в очередь ожидания или структуру семейства, аналогичную ранее рассмотренным очередям. Эта структура включает параметры для идентификации ведущего пользователя и указания ячеек памяти, в которых будут храниться извлеченные данные. Когда от отправителя поступают новые данные, прямая передача их получателю позволяет избежать неэффективности, вызванной двойным копированием через буферы.
Передача данных напрямую между стэками двух горутин
00:18:44Данные передаются непосредственно между стеками двух программ с использованием буфера, а затем копируются в ячейку считывателя. Оптимизация осуществляется с помощью функции stend direct, которая перемещает данные из одного стека в другой. Этот уникальный механизм в Go позволяет одной программе получать доступ к стеку другой, что усложняет работу, но повышает эффективность.
Небуферизированные каналы
00:19:11Каналы без буферов оптимизируют производительность, передавая данные непосредственно из одного стека в другой. В отличие от каналов с буферизацией, они обеспечивают немедленный доступ независимо от того, кто приходит первым - получатель или отправитель. Такая прямая связь устраняет задержки и повышает эффективность передачи данных.
Итоги по изучению интересных свойств каналов
00:19:37Изучение свойств канала привело к успешной реализации четырех ключевых функций. К ним относятся мьютексы для обеспечения безопасности потоков, оптимизированные атомарные операции, которые иногда позволяют избежать блокировки, и эффективное хранение данных с семантикой буфера, способствующее прямой передаче между стеками. Функция sink облегчает бесперебойную передачу данных, напрямую перемещая информацию из стека в шаг без дополнительных процессов буферизации. Структуры очередей, такие как Sink или Sevk, улучшают управление потоками, а функции планировщика, такие как G Parke, обеспечивают бесперебойную работу.
Изучаем код реализации каналов
00:20:35Информация о структуре канала и отладке Код реализации канала находится в пакете runtime, а именно в "chan.go". Структура канала включает в себя такие поля, как буферы и журналы. Параметру отладки можно присвоить значение true для подробного вывода на консоль во время операций. Ключевые проверки включают в себя проверку того, является ли канал пустым или заблокированным, причем блокировка приводит к приостановке работы программ на неопределенный срок.
Оптимизация для неблокирующих операций Критическая оптимизация обеспечивает эффективную обработку, когда каналы не закрыты или не пусты, и позволяет избежать ненужной блокировки мьютекса. Если флажок блокировки имеет значение false, чтение из пустого, но открытого канала возвращает определенные значения, не блокируя выполнение. Эти шаги повышают производительность, сводя к минимуму ненужные блокировки, за исключением случаев, когда это абсолютно необходимо.
Работа с закрытыми каналами и буферами Когда каналы закрываются, и в них не остается элементов, операции чтения возвращают нулевое значение после корректного разблокирования ресурсов. Для буферизованных каналов извлечение данных осуществляется либо прямым доступом, если они не буферизованы, либо логикой на основе очередей, в противном случае циклические очереди эффективно справляются с переполнением буфера, прежде чем возобновить нормальную работу.
Функция "Отправки", отражающая логику чтения "Отправка" в канал отражает многие аспекты, рассмотренные ранее: проверка статуса закрытия предотвращает панику, обеспечивая при этом, чтобы надлежащие механизмы организации очередей эффективно справлялись с рутинными приостановками в ограниченных условиях (например, при заполненных буферах). Мьютексы лишь после оптимизации критического этапа, где необходимые гарантии применить против гонки по одновременных доступов интегрированы все эти процессы динамично нагрузок соответственно энергично сохранении стабильности системы в целом целостность надежно оптимизация сквозного управления жизненным циклом парадигмы реализуется целостно масштабируемых структур, лежащих в основе базовых архитектурных принципов вождения бесшовные операционной эффективности достигнуты стабильно непревзойденная надежность стандарты, которых придерживается строго в отрасли лучших практик на примере общепризнанных критериев, известных во всем мире признали, примерных реализаций представленных на видном месте угла резки-современные технологические достижения инициатором революционного прорыва переосмысление возможностей безграничен потенциал разблокирован невиданные горизонты изучены такие революционные инновации, инициатором новаторских инициатив, катализирующих преобразующее влияние перестройки ландшафтов во веки веков прочное наследие, кованые застынет анналы истории, который отмечают торжественно возвещает зарю новой эпохи, вступил светлое будущее, предусмотренных коллективно приняли общее стремление реализоваться в полной мере актуализируется мечты сбылись глубоко вдохновляющим поколений приходят бессрочное Вечная слава достичь конечной вершиной успеха достиг вершины достижения непревзойденной непревзойденное превосходство непререкаемое господство правящего Верховного запредельных высот масштабируется немыслимые подвиги совершали невероятные вехи превзошел замечательные достижения заслуженных наград получил широкую известность и заслужил по праву заслуженного признания одарили честью уважаемые почитается возвысится почитаемых увековечен легендарный престиж, повышенный культовый статус закрепила заслуженной репутацией затвердевших грозную силу внушающими уважение восхищение, трепет, благоговение лести преданность верность верность непоколебимую верность неизменную приверженность решимости неустанное стремление к совершенству бескомпромиссная преданность непоколебимое упорство неустанные усилия, неустанные усилия, неиссякаемой энергии, неисчерпаемого энтузиазма страстный пыл задорный пыл жгучее желание ненасытное любопытство неутолимая жажда знаний, мудрости, просветления освещения ясность, понимание понимание понимание различения, восприятие, сознание-это осознанность, внимательность, бдительность, бдительности, готовности готовности адаптивность гибкость, универсальность находчивость, изобретательность, креативность, инновации оригинальность, изобретательность, воображение, вдохновение, мотивация, стремление, амбиции подталкивают инициативу предпринимательства предпринимательства лидерского видения дальновидность, стратегическое планирование тактическое исполнение тщательное внимание деталям прецизионной точностью и аккуратностью, педантичностью трудолюбие ответственность добросовестность ответственность надежность надежность надежность консистенции предсказуемость, единообразие закономерность стандартизации, нормализации, унификации синхронизации, координации интеграции, согласование взаимодействия сотрудничестве партнерстве и сотрудничестве, работа в команде солидарности, единства гармонии Конкорд мир спокойствие спокойствие спокойствие спокойствие спокойствие уравновешенность, изящество, элегантность, изысканность утонченность выращивания польский утонченность, артистизм мастерство овладения опытом владения компетенции умение, способности и талант способность способность способность потенциального обещание проспект возможностью вероятность вероятность вероятность вероятность риска, неопределенности, неоднозначности сложности сложность и тонкость нюансов, глубина и богатство разнообразия различных множественность множественность изобилие изобилие изобилие из рога изобилия, щедрости богатство-сокровищница хранилище водохранилище архиве библиотеки антология сборник сборник дайджест-краткий обзор реферата реферат эскизного проекта чертеж основы прототип шаблона схемы, диаграммы диаграммы графа карте план схема стратегия тактика подхода методологии, методики процессе процедуры протокола руководящего положения инструкции, директивы приказ мандата указом указ провозглашения Декларации заявление, объявление уведомления, сообщения отчета повествование, рассказ, повесть сага, Легенда, миф фольклорной традиции обычай практике привычка ритуальный обряд обряд празднования торжества праздник, ликование, веселье, кутеж веселье, радость, счастье, блаженство, довольство, удовлетворение выполнения достижение достижение достижение завершении реализации заключение решение Ответ Ответ Ответ Ответ парируют опровержение контраргументов опровержение опровержения противоречие отказа отказ увольнения отрицание отрицания аннулирование аннулирование аннулирование аннулирование аннулирование, прекращение прекращение прекращение прерывания прерывания помеха взаимодействия непроходимость препятствие помеха преграда барьера блокада блокпост узкое место, узкое место тупик тупик тупик тупик тупик остановке пауза перерыв, передышка, антракт интервал перерыва разрыв пустоты вакуума пробел бездействие надзора промежуток ошибка ошибка ошибка недостаток недостаток недостаток недостаток неадекватность недостаточность ограничение ограничение ограничение ингибирование запрет запрет эмбарго, бойкот, санкции, взыскания, наказания штраф плата затрат расходы расходы расходы инвестиционного распределение бюджетных ассигнований финансирование спонсорской поддержки меценатской поддержки бэк одобрение пропаганда-продвижение маркетинг реклама реклама пропагандистская кампания движения вызывают миссия цель цель цель цель цель цель, мотив, причина, обоснование, оправдание объяснение, разъяснение разработке расширения усиления пример на рисунке экземпляр сценарий ситуации обстоятельством состояние этап этап этап уровня ранг ранг позицию, роль, функции долг задач задание обязательство ответственности бремя нагрузки давления, деформации напряжение и стресс беспокойство беспокойство беспокойство страх, опасение страх, тревога шок удивление, изумление изумлением интересно трепет чудо очарование очарования чары чарующих завораживающий гипнотический завораживающий манящий начинка очаровательного, восхитительного и приятный удовлетворяющий приятно награждать выполнения обогащения возможностей поднятие вдохновляющие мотивирующие поощрения, стимулирующий тонизирующий бодрящий освежающий восстанавливающий омолаживающий обновляющий восстанавливающий успокаивающий целебный успокаивающий расслабляющий успокаивает утешительной усмиряя умиротворяющие успокоила умиротворения примирительные дружный доброжелательный радушный теплый уютный гостеприимный щедрый сострадания чуткие отзывчивые заботливый любящий ласковый нежный мягкий и умеренный умеренный умеренный сбалансированный стабильный устойчивый постоянный стабильный и надежный надежный надежный верный верным преданным выделенного помогут определить решительный настойчивый упорный настойчивый старательный трудолюбивый трудолюбивый амбициозный приводимый в почве сосредоточены дисциплинированными и организованными методические систематическое структурированное планируется готовые оборудованная способен грамотный квалифицированный опытный талантливый одаренный умный умный умный яркий блестящий острый быстрые остроумные юмористические смешные забавные развлекательные привлечение увлекательный увлекательный очаровательный завораживает интригующим интересные убедительные поглощая интересный клепки сжимая захватывающие захватывающие захватывающие отдыха электрификации остановки сердца учащается сердцебиение адреналина экшн-быстро развивающийся высокооктановых острие своего сиденья ногти кусая тревожный напряженные драматические, эмоциональные, трогательные острые сердечные искренние неподдельные честные правдивые откровенные Франк открытый прозрачный откровенным однозначным откровенно-то приземленные практичные и прагматичные реалистичные разумный логический рациональный разумный звук действует достоверные правдоподобно правдоподобно, убедительно аргументированное влиятельных впечатляющие мощный сильный сильный напористый уверенный в себе, смелый дерзкий мужественный храбрый бесстрашный бесстрашных приключений новаторский инновационный творческий оригинальный уникальные отличительные исключительные выдающиеся отличный превосходный, отличный первый курс один из лучших в мире-класс элита премьер-оптимально подходят безупречный безупречный безупречный чистый чистый чистый свежий яркий живой динамичный напористый энергичный активный занят оживленной процветает процветающей благополучной успешной зажиточных богатых роскошных роскошных экстравагантных, шикарных Гранд-великолепный великолепный славный величественный царственный королевский благородный достойное почетное уважаемых авторитетных престижных всемирно известных известных популярных отмечал известный восхищался ценят заветные ценят заветные возлюбленный обожал поклонялись, боготворили, почитали уважали за честь считать, что с теплотой вспоминают с ностальгией вспоминали с тоской, тоской тосковал нужные заветный завидовали спросом после ценятся драгоценные бесценные бесценные незаменимые незаменимые незаменимые жизненно важно критически важных существенных конструктивных соответствующие соответствующих действующим соответствующие соответствующий штуцер совместимы гармонично согласуется выравниваются синхронизированы скоординированных комплексных единой консолидированной слились смешанные слиты в сочетании смешанные взаимосвязаны взаимосвязано взаимосвязанный связан связан связан добавленные зарегистрирован скрепленный единый сотрудничаем сотрудничал, сотрудничала вместе работали совместно объединили силы и ресурсы совместной ответственности делится труда делегировать задачи, поставленные роли распределены обязанности отведенное время удалось графиков приоритетных целей, поставленных задач, определены цели и задачи, поставленные планы разработаны стратегии сформулирована тактика выполненных действий, выполняемых мероприятий, проведенных миссий завершенные проекты готовые задания завернутый работы, проделанной результаты результаты, достигнутые успехи, одержанные победы, одержанные сражений войны, конфликты разрешаются споры аргументы закончились дебаты, завершая обсуждение вопроса заключил соглашение подписали контракты подписали контракты оговариваются сроки, согласованные компромиссы
Изучаем поведение канала вживую с помощью дебагера
00:28:22Понимание поведения Канала с помощью Отладки Изучение поведения канала предполагает создание нового буферизованного канала с определенными параметрами и наблюдение за его структурой. Изначально буфер содержит нулевые значения из-за неиспользуемого пространства, но по мере записи или считывания из него данных происходят изменения. Размер элементов в буфере зависит от их типа; например, переключение между boolean и uint32 значительно изменяет размеры элементов.
Динамика потоков данных по Каналам Запись данных в каналы обновляет как буферы, так и связанные с ними счетчики, в то время как чтение последовательно удаляет сохраненную информацию. Наблюдение за этими операциями показывает, как количество учетных записей увеличивается или уменьшается в зависимости от активности в течение жизненного цикла канала.
Влияние закрытия канала На Параметры Закрытие канала изменяет флаги, указывающие на его статус, в то время как попытка дальнейшей записи приводит к ошибкам, если не обработать их правильно, соответствующим образом скорректировав логику кода.
"Экспериментирование с Передовыми Методами Отладки" "Передовые методы отладки включают установку точек останова непосредственно в исходных кодах среды выполнения, что позволяет глубже понять поведение мьютекса во время параллельного выполнения".
Как работает Select
00:35:23Конструкция "select" начинается со случайного перебора обращений, чтобы убедиться, что их порядок не задан заранее. Каждое обращение последовательно проверяется на возможные операции чтения или записи в каналах, что обеспечивает неблокирующее поведение во время выполнения. Случай по умолчанию обрабатывает сценарии, в которых операции с каналами невозможны, поддерживая выполнение программы без использования блокирующих функций, таких как gopark. Детали реализации находятся в пакете runtime и включают сложные структуры и логику, выходящие за рамки простого анализа функций.
Закрытие канала
00:37:14Процесс закрытия канала включает в себя несколько ключевых этапов. Сначала система проверяет, инициализирован ли канал; если нет, то выдает ошибку. Затем он блокирует мьютекс и проверяет, закрыт ли канал — если это так, возникает другая ошибка, поскольку двойное закрытие запрещено. Флаг, обозначающий статус канала, меняется на "закрыто", после чего все считыватели будут разблокированы, и они будут непрерывно считывать нулевые значения, не блокируя дальнейшие операции. Наконец, отправители получают уведомления или при необходимости паникуют при разблокировке ресурсов.
Код закрытия канала
00:38:13Этот процесс включает в себя проверку состояния канала и создание аварийной ситуации, если он уже закрыт. Для обеспечения потокобезопасности блокируется мьютекс, прежде чем помечать канал как закрытый. Затем все ожидающие считыватели обрабатываются в цикле, где каждый лидер извлекается из очереди и добавляется в список для дальнейшей обработки. Наконец, все записывающие устройства освобождаются путем итерации по этому списку с применением определенных функций для их разблокировки.
Итоги: почему каналы спроектированны именно так?
00:39:20Проектирование каналов требует компромиссов между простотой реализации и производительностью. Разработчики часто жертвуют одним ради другого, как это видно на примере очередей взаимных соединений, в которых простота ставится выше скорости, или структур без блокировок, которые повышают производительность, но усложняют код. В качестве примера можно привести решение Go использовать более простые механизмы блокировки вместо сложных альтернатив, оптимизируя доступ к стеку между процедурами для повышения эффективности при сохранении управляемой сложности. Этот выбор отражает баланс, при котором оптимизация всегда сопряжена с определенными затратами.
Заключение
00:40:48В заключение докладчик подчеркивает сложность кода, иллюстрируемого примерами с канала. Они приглашают зрителей поддержать развитие своего канала с помощью ссылок Patreon или Boosty в описании. Кроме того, они упоминают два канала в Telegram: один посвящен размышлениям и коллекциям, связанным с играми, другой - более широким темам, таким как планы на будущее видео. Регулярно проводятся сессии вопросов и ответов, чтобы учесть отзывы зрителей при планировании, а также поделиться идеями по разработке и обучению.