Game Development | YeaHub
375 subscribers
151 photos
192 videos
529 links
Теория, подготовка к интервью и курсы для Game Dev разработчиков

YeaHub — это платформа для IT-специалистов, объединяющая обучение, карьерный рост, развитие и сообщество единомышленников.

Платформа: https://yeahub.ru

Для связи: @ruslan_kuyanets
Download Telegram
Forwarded from YeaHub
👨🏻‍💻 Сервис лайвкодинга в YeaHub

Фактически — релиз уже состоялся.
Но честно: мы не успели загрузить ту огромную базу задач, которую планировали, и ещё не всё успели полноценно протестировать.

Поэтому до 23 февраля работаем в режиме «вместе доделываем продукт»:
— мы активно добавляем задачи и чиним баги, все
— пока тестируем, все задачи открыты, после этого примерно 50% закроем для членов
— вы решаете, находите проблемы, пишете в поддержку и даёте фидбек
— ну и оформляете подписку 😜

Что уже есть:
• база реальных задач с собеседований
• JavaScript / Python / Java / Go
• удобный редактор и проверка решений

Что скоро:
• связь задач с компаниями и коллекциями собеседований (не успели в этот релиз)
• другие языки
• контесты
• обучающие модули и курс по алгоритмам
• AI-разбор решений построчно
• челленджи и соревнования

👉 Задачи: https://yeahub.ru/dashboard/tasks

👉 Членство: https://yeahub.ru/dashboard/settings#select-tariff

Новогодние цены действуют только до полноценного запуска. После — x2.
Сейчас лучший момент подключиться и поддержать проект.


Спасибо, что помогаете нам запустить это правильно✊🏻🚀💪
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
2
#Собес #collections #data_structures
🤔 Как подойти к выбору коллекции для задачи? Как учитывать алгоритмическую сложность при выборе?

💬 Кратко:

Выбор коллекции начинается с анализа операций: частые вставки, удаления, поиск или доступ по индексу. Учитывайте алгоритмическую сложность операций - O(1) для константного времени, O(n) для линейного. List подходит для частого доступа по индексу, Dictionary для быстрого поиска по ключу, HashSet для проверки принадлежности.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
Продолжаем углубление в методы Update - Рассмотрим поведение FixedUpdate при зависании

Давайте попробуем ответить на вопрос, который мне задавали на собесе:
Если игра зависла на 2 секунды, то какое будет поведение FixedUpdate в восстановившийся кадр?
Если мы знаем, что FixedUpdate работает зафиксированное время, то что делать, если время прошло, а операция не выполнилась?


Из того, что мы знаем о FixedUpdate, напрашивается очень неприятный вывод.
Если Fixed Timestep установлен в 0.02 секунды, это означает, что физика должна обновляться 50 раз в секунду. Прошло 2 секунды? Значит Unity должен вызвать FixedUpdate 100 раз, чтобы физика "догнала" реальное время.

Но это катастрофа! Если Unity в одном кадре начнёт вызывать FixedUpdate сто раз подряд, это займёт огромное количество времени и игра зависнет ещё сильнее. Следующий кадр тоже будет долгим, что потребует ещё больше вызовов FixedUpdate, и так далее. Это называется "спиралью смерти" производительности.

Но это не происходит, потому что я не сказал вам про ещё одну важную составляющую FixedUpdate. Это - Maximum Allowed Timestep, который располагается в настройках рядом с Fixed Timestamp и по умолчанию равняется 0.3333333.
Эта настройка ограничивает количество времени, которое Unity тратит на обработку физики и вызовов FixedUpdate в течение одного кадра в секундах.
Если обработка кадра занимает больше времени, чем Maximum Allowed Timestep, физический движок не пытается симулировать дополнительное время, превышающее Maximum Allowed Timestep, и вместо этого позволяет обработке кадра завершиться, после чего возобновляет работу так, как будто время не прошло.

Детальнее. У нас Fixed Timestep равен 0.02 секунды, Maximum Allowed Timestep равен 0.33 секунды. Игра зависла на 2 секунды.
Без ограничения Unity должен был бы вызвать FixedUpdate сто раз (две секунды разделить на 0.02 секунды). Но с ограничением в 0.33 секунды максимум он может вызвать примерно шестнадцать раз (0.33 разделить на 0.02).
Как это выражается в поведении физики на сцене? Предположим, мы симулируем полёт пули, скорость которой равняется 100 метров в секунду. За 2 секунды она должна была пролететь 200 метров, но из-за зависания, она пролетит только 33 метра.

0.33 сек : 0.02 сек = 16-17 вызовов, в зависимости от дробной части (Пока возьмём 16)
16 вызовов * 0.02 сек = примерно 0.33 сек
100 м * 2 сек = 200 м - сколько она должна пролететь
Но из - за ограничения выходит вот так:
100 м * 0.33 = 33 м


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

Следующий пост будет финальным, в котором мы рассмотрим поведение Update и LateUpdate при зависании.

🚀 Пост Guru Unity: @Minerope
Please open Telegram to view this post
VIEW IN TELEGRAM
#Собес #unity #csharp
🤔 Что делал, чтобы уменьшить мусор при инициализации Spine-анимаций?

💬 Кратко:

Чтобы уменьшить GC при инициализации Spine, использовал кэширование анимаций и скелетов, избегал частого создания/уничтожения Spine GameObject, применял object pooling для анимированных объектов, и минимизировал runtime изменения скинов и аттачментов.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#Собес #postgres #copy #insert
🤔 В каких случаях стоит использовать COPY вместо INSERT в Postgres?

💬 Кратко:

COPY стоит использовать при массовой загрузке данных. Он работает значительно быстрее INSERT, потому что минимизирует накладные расходы и сетевые round-trip.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#video #unity
📚 FREE Complete Unity Game Development Courses

Полный бесплатный курс по разработке игр на Unity — от базовых уроков для начинающих до продвинутых тем, охватывающий основы интерфейса, C#-скрипты, 2D/3D-разработку и практические проекты, чтобы помочь вам освоить Unity и создать собственные игры шаг за шагом

Перейти к материалу

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#Собес #synchronization #context #async
🤔 Что делает synchronization context?

💬 Кратко:

Synchronization Context - это механизм, который управляет тем, в каком потоке выполняется код после асинхронной операции. Он обеспечивает, что код продолжает работать в правильном контексте, например, в основном потоке UI. В Windows Forms и WPF он гарантирует, что обновления интерфейса происходят только в UI-потоке. Без него асинхронные операции могли бы завершаться в случайных потоках, что привело бы к ошибкам при обновлении элементов управления.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
Как работают Update и LateUpdate

Завершаем цикл постов про методы Update. Сегодня разберём, как ведут себя Update и LateUpdate, если игра подвисает.

Эти методы работают очень просто: кадр вызвался → методы вызвались.

Они не пытаются “догнать” пропущенные вызовы, как это делает FixedUpdate.
То есть один кадр = один вызов метода.

Теоретически при длительном зависмании нас может спасти Time.deltaTime, потому что он учитывает время между кадрами. Но тут есть важный нюанс.

У Time.deltaTime есть ограничение - Time.maximumDeltaTime (в инспекторе это Maximum Allowed Timestep).

Это означает, что значение Time.deltaTime никогда не будет больше ~0.333 секунды.

Подробнее можно почитать в документации:
https://docs.unity3d.com/ru/530/Manual/TimeFrameManagement.html
https://docs.unity3d.com/6000.3/Documentation/Manual/time-handling-variations.html

Как это выглядит на практике

Вспомним простой код движения:

private void Update()
{
transform.position += Vector3.forward * 10f * Time.deltaTime; // 10 м/с
}


Если игра подвиснет на 2 секунды, то Time.deltaTime всё равно будет равен 0.33.

В итоге - ожидали пройти 20 метров, а фактически пройдём 3.3 метра. Потому что deltaTime ограничен.

Можно ли это исправить?

Технически - да.

Можно использовать:

• Time.unscaledDeltaTime - deltaTime без ограничений
• Time.realtimeSinceStartup - реальное время с момента запуска приложения

Но это почти всегда плохая идея для игровой логики.

Если игра подвиснет, объект может “телепортироваться” на большое расстояние.

Кроме этого:
• физика не будет успевать за объектом
• логика станет сложнее
• нагрузка на CPU может увеличиться

По сути, можно раскрутить “спираль смерти”-— когда из-за лагов система начинает лагать ещё сильнее.

Когда это всё-таки имеет смысл


Использовать unscaledDeltaTime имеет смысл там, где важно реальное время, а не игровое.

Например, для таймера UI:

private void Update()
{
_uiTimer += Time.unscaledDeltaTime;
UpdateUITimerText(_uiTimer);
}


А что насчёт LateUpdate?

LateUpdate работает по тем же принципам, что и Update.
Единственная разница - порядок вызова. Сначала Update, потом LateUpdate.

То есть всё, что мы разобрали про Update (ограничение deltaTime, поведение при фризах и т.д.), полностью применимо и к LateUpdate.
Если понимать эти механизмы под капотом, можно без труда отвечать на каверзные вопросы на собеседованиях и, что важнее, писать более предсказуемую игровую логику.

🚀 Пост Guru Unity: @Minerope
Please open Telegram to view this post
VIEW IN TELEGRAM
#Собес #dns #ip
🤔 Что происходит после получения IP-адреса?

💬 Кратко:

После получения IP клиент выбирает маршрут и пытается установить соединение с сервером. Обычно сначала выполняется установление TCP-соединения, а если сайт по HTTPS — дополнительно идёт TLS-рукопожатие. Затем клиент отправляет HTTP-запрос и получает HTTP-ответ. Дальше браузер начинает обработку ответа и загрузку связанных ресурсов.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#video #начинающие
📚 Сборник видео для Джунов

Здесь собраны все видео с канала Лавка Разработчика, которые подходят для тех, кто находится на старте вхождения в видеоигровую индустрию, понимает самые базовые вещи в программировании и хочет развиваться в этом направлении далее

Перейти к материалу

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
2👍1
#Собес #linq #ienumerable #deferred_execution
🤔 В чём заключается классическая проблема с IEnumerable и отложенным выполнением в LINQ?

💬 Кратко:

Классическая проблема возникает, когда LINQ-запрос (который выполняется отложенно) оценивается более одного раза, особенно если источник данных или вычисления внутри запроса изменяются или являются "дорогими". Это может привести к неожиданным результатам (если данные изменились между оценками) или к серьёзным проблемам с производительностью (если сложные вычисления повторяются).

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
1
Давайте немного отдохнём от больших серий статей и разберём один вопрос с собеседования.

"Как бы ты реализовывал тип данных, который даёт значение с точностью до 100 знаков после запятой?"


Это была очень крупная известная компания, которая работает со своим собственным движком.

Из структуры вопроса видно, что он подразумевает размышления.
Собеседующему интересно, какие варианты ты предложишь и как ты к ним придёшь. Даже если ты ошибёшься - это будет не так страшно, если ты действительно показываешь обоснованную цепочку выводов, к которым приходишь. Поэтому не бойтесь размышлять вслух.

Первое, что приходит мне в голову - это использование Nuget пакета для подобной ситуации.
Я знаю точно, что существует решение для случаев, когда тебе нужно очень большое целочисленное число. Пакет называется BigInteger. Я бы поискал нечто подобное в интернете.
Спойлер: решения реально существуют. Библиотеки Mpir.NET и Math.NET Numerics.

Второе, что приходит мне в голову - это ресёрч библиотеки Mathf, в поисках уже готового решения.
Спойлер: я не нашёл. Но вариант звучит вполне разумно для собеседующего.

Третье - попробовать реализовать решение самостоятельно. Как это сделать? Давайте посмотрим на саму реализацию.
using System;
using System.Text;

public static string DivideLong(long a, long b, int digits)
{
if (b == 0)
throw new DivideByZeroException();

// negative будет true, если знаки чисел a и b различаются (одно положительное, другое отрицательное)
// Знак ^ - это побитовая операция XOR (исключающее ИЛИ)
// После этого приводим их абсолютными значениями (убираем минус в начале)
bool negative = (a < 0) ^ (b < 0);
a = Math.Abs(a);
b = Math.Abs(b);

// Целая часть
long integerPart = a / b;
// Остаток
long remainder = a % b;

StringBuilder result = new();

// Добавляется знак минус, если результат отрицательный и при этом не является нулём (условие (integerPart != 0 || remainder != 0) гарантирует, что для -0 минус ставиться не будет
if (negative && (integerPart != 0 || remainder != 0))
result.Append('-');

result.Append(integerPart);

// Разберём детальнее ниже
if (digits > 0)
{
result.Append('.');

for (int i = 0; i < digits; i++)
{
remainder *= 10;
long digit = remainder / b;
result.Append(digit);
remainder %= b;
}
}

return result.ToString();
}


Для каждого требуемого знака после запятой выполняется:
- Остаток умножается на 10;
- Определяется текущая цифра как целая часть от деления полученного числа на делитель b;
- Цифра добавляется к строке;
- Остаток заменяется остатком от деления на b.

Этот цикл повторяется ровно digits раз, формируя последовательность десятичных знаков без округления.

У этого решения есть свои слабые места. Я вижу несколько редких ситуаций, которые могут сломать логику. Но это здесь не так важно.
Главное, что вы:
- Понимаете суть алгоритма и на чём он строится.
- Примерно понимаете как нужно отвечать на вопросы подобного рода.

🚀 Пост Guru Unity: @Minerope
Please open Telegram to view this post
VIEW IN TELEGRAM
1
#Собес #linq #ienumerable #deferred_execution
🤔 В чём заключается классическая проблема с IEnumerable и отложенным выполнением в LINQ?

💬 Кратко:

Классическая проблема возникает, когда LINQ-запрос (который выполняется отложенно) оценивается более одного раза, особенно если источник данных или вычисления внутри запроса изменяются или являются "дорогими". Это может привести к неожиданным результатам (если данные изменились между оценками) или к серьёзным проблемам с производительностью (если сложные вычисления повторяются).

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#Собес #decapsulation #data_processing #osi_model
🤔 Что происходит в модели OSI, когда пакет данных перемещается от нижнего к верхнему уровню?

💬 Кратко:

Когда пакет данных перемещается от нижнего к верхнему уровню модели OSI, заголовки, добавленные ранее, удаляются, и остаются только исходные данные.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#repository #godotengine
📚 Godot Engine

Официальный исходный код открытого кросс‑платформенного игрового движка Godot. Это полноценная среда для разработки 2D‑ и 3D‑игр, включающая редактор, скриптовый язык GDScript (похожий на Python), систему сцен и узлов, инструменты анимации, физику и рендеринг. Репозиторий содержит всю кодовую базу движка, документацию, примеры, а также систему отслеживания задач и обсуждений. Подходит как для изучения архитектуры движка, так и для внесения собственных изменений, создания плагинов или сборки кастомных версий.

Перейти к материалу

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
🔥1
#Собес #addressables #grouping
🤔 Как лучше организовывать группы и бандлы Addressables для оптимальной загрузки?

💬 Кратко:

Группы и бандлы нужно организовывать по логическим модулям: общие ассеты помещаются в shared группы, UI — в отдельные мелкие бандлы, уровни — в крупные пакеты, а preview-ассеты — в отдельные лёгкие группы. Важно контролировать зависимость бандлов, избегать duplication через Analyze Tool, и выбирать тип упаковки (Pack Together / Pack Separately) в зависимости от частоты загрузки. Главная цель — минимальное количество больших скачиваний и отсутствие дубликатов ассетов.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#Собес #transaction_isolation #serializable #concurrency
🤔 Какой уровень изоляции транзакций в PostgreSQL поможет избежать конфликтов при параллельной обработке задач?

💬 Кратко:

Уровень REPEATABLE READ или SERIALIZABLE поможет избежать конфликтов при параллельной обработке задач. Однако в большинстве случаев достаточно REPEATABLE READ, который предотвращает непредсказуемое поведение за счёт повторного чтения одинаковых данных в рамках одной транзакции.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#roadmap #unity #roadmap
📚 Дорожная карта Unity-разработчика 2025: с нуля до джуна

Статья представляет собой дорожную карту для начинающих Unity-разработчиков, которая охватывает весь путь от освоения основ языка программирования C# до работы с физикой, сторонними SDK и другими аспектами разработки игр в Unity. В ней подробно расписаны ключевые темы, которые необходимо изучить: основы C#, объектно-ориентированное программирование, работа с коллекциями и данными, паттерны проектирования, архитектура Unity, программирование в контексте движка, физика, визуал и звук, работа с ресурсами, пользовательский интерфейс и многое другое. В конце статьи приведены полезные ссылки на ресурсы для обучения

Перейти к материалу

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#Собес #file #file_handling #c#
🤔 Что такое работа с файлами в C#?

💬 Кратко:

Работа с файлами в C# включает в себя операции чтения и записи данных в файлы. Для этого используется пространство имен System.IO, которое предоставляет классы для работы с потоками ввода и вывода. Потоки — это последовательности байтов, через которые происходит взаимодействие с файлами. В C# существуют два типа потоков: входной (для чтения) и выходной (для записи в файл).

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа
#Собес #boxing #unboxing #reference_type
🤔 Что такое упаковка (boxing) и распаковка (unboxing) в .NET и зачем они нужны?

💬 Кратко:

Boxing — это упаковка значения value type в объект object (на куче), а unboxing — извлечение значения обратно в value type. Необходимы для прозрачной работы с общим базовым типом object или интерфейсами. Упаковка создаёт дополнительный объект и копирует данные, распаковка проверяет тип и снова копирует, что может влиять на производительность.

📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору

📣 Все для прокачки навыков:
Анонсы → канал
Комьюнити → чат
База задач и вопросов → платформа