Недавно я проходил собеседования в игровых студиях на младшего программиста графики. По итогу я узнал, каких навыков они ожидают от начинающего программиста и какие вопросы могут задать. В этой статье я собрал вопросы в удобный список. Смысл в том, чтобы другие начинающие программисты могли использовать его для подготовки, прежде чем идти на первое собеседование. Но хочу оговориться, что я не рекомендую просто запоминать ответы на эти вопросы. Темы в списке — это темы, которые следует понять и освоить, чтобы решать реальные проблемы программирования графики. Их нужно понять, а не запомнить ответы.

Вопросы делятся по темам: С++, математика, оптимизация и компьютерная графика. Очевидно, это главные темы в повседневной работе. C++ часто используется в реальных задачах, поэтому естественно, что на собеседовании задают много вопросов по нему. Кроме того, в программировании графики требуется лучшее знание математики, чем в большинстве других видов программирования, поэтому математические навыки имеют первостепенное значение. Наконец, для достижения 60 FPS и рендеринга с высокой графической точностью обязательными являются сильные навыки оптимизации. Давайте рассмотрим популярные вопросы в каждой категории.

Вопросы по C++


  • Когда следует использовать виртуальные деструкторы? (Интервьюеры в совершенном восторге от этого вопроса!)
  • В чём разница между выделением памяти в куче и стеке?
  • Какие фичи C++11 и C++14 вы используете?
  • Для чего используются шаблоны?
  • Объясните ключевое слово inline.
  • Что такое прямой и обратный порядок байтов (от старшего к младшему и от младшего к старшему)?
  • Объясните, что такое const-корректность.
  • Какие накладные расходы связаны с вызовом виртуальной функции?
  • Вероятно, в каком-то вопросе вас попросят выполнить некие трюки по жонглированию битами с помощью операторов вроде &, / и им подобным.
  • Вероятно, в каком-то вопросе вас попросят что-то сделать со структурами данных, связанными указателями, вроде дерева. Например, обратить связный список.
  • Каков размер указателя в C++ (то есть что показывает sizeof для указателя)?

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

Вопросы по математике


На самом деле вопросы по математике довольно однообразны.

  • Что такое скалярное произведение?
  • Что такое векторное произведение?
  • Почему следует использовать кватернионы вместо углов Эйлера?
  • Как применить матрицы для преобразования объекта? Например, как с помощью матриц масштабировать, преобразовать и повернуть объект?
  • Как рассчитать пересечение между лучом и плоскостью/сферой/треугольником?
  • Объясните концепции пространства мира, пространства объектов и пространства камеры.

Вероятно, предложат решить некоторые практические задачи, связанные с использованием скалярных произведений, векторных произведений и кватернионов.

Вопросы по оптимизации


  • Как применить иерархию ограничивающих объёмов (или octree, или что-то подобное) для ускорения трассировщика лучей?
  • Расскажите о кэш-памяти (кэши L1, L2 и так далее).
  • Что такое дизайн на основе данных?
  • Объясните, как оптимизировать отсечение по пирамиде видимости с помощью многопоточности и SIMD (например, см. пост в блоге Андреаса Асплунда).
  • У вас есть опыт использования инструментов профилирования производительности для GPU?

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

Вопросы по компьютерной графике


  • Какие вы знаете методы сглаживания (варианты: MSAA, MLAA, FXAA и TXAA)?
  • Каковы типичные элементы движка рендеринга (например, система для обработки отсечения по пирамиде видимости, рендеринга теней, обработки источников света с чем-то вроде отложенного/прямого затенения, система обработки материалов в движке и проч.)?
  • Какие вы знаете методы генерации теней (есть КУЧА техник генерации теней, например, разностные теневые карты, сглаживание порога с помощью экспоненциальной функции и более свежий метод моментов)?
  • В чём плюсы и минусы отложенного рендеринга?
  • Объясните, что такое физически корректный рендеринг?
  • Можете объяснить, как работает уравнение рендеринга?
  • Что такое BRDF? Что имеют в виду, когда говорят, что «BRDF сохраняет энергию»?
  • Как сказываются на производительности ветвления в шейдере (подсказка: почитайте о концепции варпов в архитектуре GPU)?
  • Какие преимущества у новых API, таких как Vulkan и DirectX 12, по сравнению со старыми OpenGL и DirectX 11 (подсказка: главное — сниженная нагрузка на драйвер)?
  • Какую последнюю научную статью по графике вы читали, можете ли её объяснить (это довольно распространённый вопрос)?
  • Опишите весь графический конвейер (вероятно, ответ будет довольно длинным. Вы расскажете о вершинном шейдере и фрагментном шейдере, о перспективно-корректной интерполяции, о Z-буфере, о двойной буферизации фреймбуфера, об альфа-смешивании, матрицах преобразования, однородных координатах, моделях отражения во фрагментном шейдере и так далее).

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

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

Некоторые из вас ещё учатся и выбирают предметы учебной программы для работы в компьютерной графике. Мой совет — сосредоточить усилия в первую очередь на высокопроизводительных вычислениях и прикладной математике. Из предметов по программированию попробуйте освоить многопоточность, компьютерную архитектуру и GPGPU, а также другие темы, связанные с высокопроизводительными вычислениями. Из курсов математики — линейная алгебра, многомерное исчисление (думаю, в США этот курс называется Calculus III), теория вероятностей, численная оптимизация, дифференциальные уравнения и вычислительная геометрия. В первую очередь сосредоточьте внимание именно на прикладной математике, а не на более абстрактных математических темах, таких как топология и абстрактная алгебра, поскольку они не так нужны в компьютерной графике.

В общем, от вас не ожидают, что вы разбираетесь во всех нюансах компьютерной графики. Понятие «компьютерная графика» охватывает широкий диапазон тем, таких как глобальное освещение, отбраковка с учётом препятствий (occlusion culling), генерация теней, трассировка пути, жидкостное моделирование, обработка геометрии, GPGPU, физически корректный рендеринг и так далее. Было бы неразумно ожидать, что джун знает все нюансы этих тем. Но если вы что-то укажете в резюме, будьте готовы подробно ответить на эту тему.

Таким образом, не нужно знать ВСЁ о компьютерной графике. Часто бывает, что вас просят рассказать о главных проектах, над которыми вы работали. Затем интервьюер задаст много дополнительных вопросов и попросит подробно объяснить детали вашего проекта. Поэтому мой совет: перед собеседованием выберите несколько проектов, которыми особенно гордитесь — и готовитесь к подробному объяснению.

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

Комментарии (49)


  1. konshyn
    21.03.2018 11:45
    +7

    Что такое точечный продукт?

    Садитесь, кол!


  1. Suvitruf
    21.03.2018 14:00

    Какую последнюю научную статью по графике вы читали, можете ли её объяснить (это довольно распространённый вопрос)
    о_О


    1. Marui
      21.03.2018 14:35
      +4

      А что не так? Статья претендует на «Программиста графики», а не на Engine/Gameplay/Animation/General программист. тут скорее имелось в виду «Расскажите что-нибудь с последнего SIGGRAPH»


      1. Suvitruf
        21.03.2018 14:49

        Если для «Программиста графики» требуется читать научные статьи, то от «Engine developer» будут требовать чтение научных статей по матану?

        Моя главная претензия именно к термину «научный». Может имелись ввиду «технические статьи»?


        1. Marui
          21.03.2018 14:57

          What is the last graphics paper you read, and can you explain it to me?(this was a pretty common question)


        1. Shekeen
          21.03.2018 16:07

          Чем «технические статьи» не «научные»? Вот, например, ссылка из этого поста на статью: cg.cs.uni-bonn.de/aigaion2root/attachments/MomentShadowMapping.pdf

          А так программирование графики — это вполне себе R&D, там активно публикуют научные статьи, выступают на, например, вышеупомянутом SIGGRAPH. У «Как делают игры» пара выпусков подкаста посвящены программированию графики, они относительно старые, но их хватит для базового понимания работы графического программиста
          kdicast.com/e/69-petr-sikachev-iz-eidos-o-programmirovanii-grafiki
          kdicast.com/e/116-siggraph-2015-i-grafika-v-igrah


          1. Suvitruf
            21.03.2018 16:08
            +1

            Статьи на хабре могут быть техническими, но они не научные. Научные, для меня,- это статьи в аккредитованный журналах.


            1. Shekeen
              21.03.2018 16:50

              Хорошо, тот мой вопрос и плохой, и не к месту. Мне непонятно, почему вас удивляет, что интерес к научным статьям является одним из критериев оценки графического программиста?


              1. Marui
                21.03.2018 16:59

                Научное = непроверенное на продакшене. Программирование графики это как «нарисовать сову». Рисуешь тень для куба… рисуешь тень на террабайтном террейне на андроиде в 120 fps (8ms)


              1. Suvitruf
                21.03.2018 16:59
                -1

                Удивляет, потому что это бесполезный вопрос, который тратит и время собеседующего, и время собеседуемого. Почти со 100% вероятностью можно сказать, что если кандидат назовёт научную статью, то собеседующий её не читал и, зная специфику научных статей, маловероятно, что он вникнет в объяснения.


                1. mclander
                  21.03.2018 17:25

                  Это вопрос-ловушка.

                  Весь фокус во втором вопросе: «Расскажите, что вы вам помогла понять эта статья?»



                1. dom1n1k
                  22.03.2018 01:24

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

                  «Научная статья» звучит страшно, но на самом деле во многих из них ничего особо страшного нет, и там бывает можно найти реально полезные для практики техники, алгоритмы и тд. Например, я читал около десятка статей по алгоритмам построения выпуклой оболочки. Те куски, где автор пускается в сухие математические доказательства — пропускал. Но саму идею метода, в чем его плюсы и минусы — почерпнуть несложно. И понимание получается намного более цельным и системным, чем если прочитать пару обзорных статеек на том же Хабре.


                  1. Suvitruf
                    22.03.2018 17:21

                    Заинтересованность — это хорошо. Но, скажем, если человек не читает научные статьи — это будет плюс или минус? Это просто факт. Я к тому, что не совсем понимаю, как это поможет в принятие решения о найме.


                    1. dom1n1k
                      22.03.2018 19:12
                      +2

                      Если не читает — это минус относительного другого кандидата, который читает.
                      Не решающий, не фатальный, но всё же.


            1. bitlemon
              21.03.2018 18:46
              +2

              в аккредитованных журналах
              Вы, наверное, хотели сказать "в реферируемых"?


              1. Suvitruf
                21.03.2018 19:06

                Хм, видимо с аккредитацией СМИ напутал. Спасибо за поправку.


              1. DistortNeo
                21.03.2018 22:37

                Вы, наверное, хотели сказать «в рецензируемых»?


                1. bitlemon
                  22.03.2018 02:52

                  Да нет, я написал ровно то, что хотел :)
                  Ваш вариант, пожалуй, более правильный по-русски, но мне ближе калька с английского, а, судя по Википедии, можно и так и так.


                  1. mickvav
                    22.03.2018 08:57

                    Статья на хабре (вкупе с комментами, конечно) зачастую куда более толковая вещь, чем статья в абы-каком научном журнале. Особенно — на технологическую тему. Если в приличном журнале редактор перекинет твою статью 2-3-м людям, которых он считает специалистами в теме, они тебя попинают по делу, ты доработаешь и статью выкатят, то в средне-фиговом — это будет доцент с соседней кафедры, который в лучшем случает поправит какие-то совсем тупые нестыковки, и оно вылезет. На хабре же придёт куча народу (если тема интересная и картинку покрасивее воткнуть), и пинать будут нещадно, и комменты видны — рецензии же сильно не все журналы публикуют.


                    1. kokoko321
                      22.03.2018 15:30

                      До публикации в журналах публикуют препринты на arxiv.org, где сможет пнуть кто угодно.


                      1. mickvav
                        22.03.2018 16:51

                        А где там комменты можно почитать?


  1. myxo
    21.03.2018 14:15
    +3

    Ох, вы промптом переводили, что ли? Большая састь вопросов просто некорректна. А перевести features как функция — это, конечно, особое видение.
    ps. Знаю, что такое обычно в ЛС пишут, но тут куда не ткни — ошибка.


  1. dimkss
    21.03.2018 15:10

    Сколько собеседований вы прошли? Большая выборка?


  1. musicriffstudio
    21.03.2018 15:23
    +1

    если перейти по ссылке на оригинал. Судя по фото автора и примера его работ это юный сапожник без сапог.


    1. ganqqwerty
      21.03.2018 18:35

      обычный вчерашний студент, вроде


  1. Maur
    21.03.2018 15:40
    +1

    Как показывает практика, книги, собственный опыт проведения собеседований, да и подтверждают давние дискуссии на различных технических площадках (за последние 15-20 лет) список вопросов почти один и тот же, а вот список «правильных» ответов на эти вопросы всегда меняется из года в год и от одной головы к другой.


  1. RomanArzumanyan
    21.03.2018 16:12

    Что такое прямой и обратный порядок байтов?

    Это вы так про little- и big- endian???


    1. Marui
      21.03.2018 16:17
      +1

      Да, это оно. Вопрос просто для того знаком ли человек с бинарной совместимостью. И что бывает разное выравнивание, порядок байт. Что бинарный фаил на одной платформе не будет читаться на жругой.


  1. mclander
    21.03.2018 17:23
    +1

    Начинающий программист? Хорошо что я фронтендер.

    Мне никто не задавал вопросов, скажем, о том как JS реализует механизм Proxy в движке V8.


    1. Keyten
      21.03.2018 22:29

      Ну так-то на собеседованиях вполне себе спрашивают, что там внутри движка. Например, чем отличаются следующие две конструкции?:

      function Class1(){}
      Class1.prototype.func1 = function(){};
      Class1.prototype.func2 = function(){};
      
      function Class2(){}
      Class2.prototype = {
        func1: function(){},
        func2: function(){}
      };
      


      1. TheShock
        22.03.2018 03:48

        Про недостаток конструктора не каждый догадается. Вообще довольно сложный вопрос для собеседования. Я вот даже не уверен не забыл я чего еще. Я любил задавать такие вопросы. Следующий вопрос задаю по мере того, как человек отвечает на предыдущий.

        1. Что выведет этот код?
        2. Почему так происходит?
        3. Как бы вы его переписали, чтобы избежать неявного поведения?

        function MyClass (name) {
           this.options.name = name;
        }
        
        MyClass.prototype.options = {
           name: "Default name"
        };
        
        var foo = new MyClass("foo");
        var bar = new MyClass("bar");
        
        console.log(
           foo.options.name,
           bar.options.name
        );


  1. AllexIn
    21.03.2018 19:54

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


  1. sbh
    22.03.2018 03:12

    Да что за вопросы то такие?!
    На них реально многие знают ответы?


    1. TheShock
      22.03.2018 03:59

      Я вот на значительную часть представляю ответ. Но гарантирую, что если бы я писал графический движок, то на большинство знал бы ответ, ибо смутно представляю, как без знания ответов на них написать движок рендеринга для современной 3д-игры. Большинство вопросов по математике — это минимальная база, которая необходима для написанияч шейдеров. Чтобы знать ответ на вопрос про кватернионы — достаточно слышать о gimbal lock, сложнее будет, если попросят написать пример кватерниона — там уже без опыта не обойтись.

      Как можно написать графический движок, если ты не знаешь, как создать тени (а они зависимо от требований реально должны создаваться разными способами), если не знаешь алгоритмов сглаживания, Forward vs Deferred рендеринг — два основных подхода сейчас, PBR — это то, как создаются материалы и считается отражение света от них.

      Серьезно, я вот прочитал вопросы, я понимаю их все (пусть и знаю ответы только поверхностно), но гарантирую, тот, кто занимается созданием графического движка не сможет работать без знания ответов на них.


      1. AllexIn
        22.03.2018 08:26
        +5

        Я писал много движков, с нуля.
        Писал собственную мат либу.
        Но яне смогу ответить на вопрос ка кнайти пересечение прямой и плоскости. Ну так то ответ очевиден, уроавнение прямой + уравнение плоскости. Но я навскидку не помню уроавнения плоскости. Занятно, пока писал что не помню — вспомнил. Оно примитивное и я его понимаю, а не помню.
        Ну ладно, забудем про прямую и плоскость. Есть миллион важных для прогера движка формул. Я их не помню. Либу для кватернионов я писал тупо по методичке, потому что осилить их суть не смог(правда и не особо пытался). При этом либа вполне работает.
        ПРостой пример, который всегда привожу: я не смогу без гугеля написать инициализацию OpenGL 3. Делал это много раз. Но как в деталях делается не помню. Суть помню: Формат пикселя->инициализация контекста->загрузка расширений->повторная инциализация контекста.
        Но написать кодом не смогу. Не помню и не понимаю зачем мне это помнить.

        Я не понимаю какое отношение трассировка лучей имеет к разработке графического движка.Сходу вот так типичных примеров не могу вспомнить, где он был бы нужен. Как минимум настолько, чтобы в нём досканально разбираться.

        При этом совсем нет вопросов про граффический конвеер, которые как минимум также важны как понимание кэша.


        1. TheShock
          22.03.2018 09:38
          +3

          При этом совсем нет вопросов про граффический конвеер, которые как минимум также важны как понимание кэша.

          Последний вопрос как раз про графический конвеер.

          Мне кажется, что все, что вы написали — было бы достаточно. Ну то есть к примеру ответить: «уроавнение прямой + уравнение плоскости, но навскидку не вспомню их» вполне достаточно.

          Либу для кватернионов я писал

          Вы видели вопрос в топике? Зачем кватернионы, если есть углы Эйлера, которые попроще. Смогли бы ответить?

          Суть помню

          Мне кажется, что на собесе вполне подошел бы такой ответ.

          Вот вы можете сказать чем отличается Forward от Deferred рендеринга? Я уверен, что сможете. Из каких текстур состоят материалы, что такое шероховатость, карта нормалей, карта альбедо? Уверен, что тоже сможете.

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


          1. Marui
            22.03.2018 09:55
            +3

            90% собеседований спрашивают теорию и сферические алгоритмы в вакууме. 90% времени на работы вы будете воевать с API и инструментарием. Тоесть если вы забыли какие-то API GL, то всем пофигу. Если вы не можете нарисовать на доске картинку PBR, то уже хуже. Основная задача проверить, что вы не будете впадать в ступор и паниковать при виде такого или иного круга задач.


            1. mclander
              22.03.2018 12:29
              +1

              У меня для собеседований есть кусок полуговнокода. Прошу просто прочитать его и сказать по русски что он на самом деле делает.

              Тест близкий к идеальному;)

              Это в США культура собеседований, где принято тратить на собеседование много времени в любой компании. И ты знаешь, что конкуренты действуют также. А у нас если не сделаешь адекватному товарищу оффер в первые три дня его поиска работы, то искать будешь ещё долго.

              Поэтому, если бы я собеседовал на графику, то адеквату просто дал бы задачу на то же пересечение прямой плоскости. И 10-20 минут за компом с инетом. И по PBR задал вопрос и при «не аллё», дал бы 5 минут в интернете и попросил бы своими словами описать, что это за зверь. И как и где его можно использовать или не использовать или как сделать вид, что его использовали.

              И оценивал не только «схватывание», а насколько человека заинтересовало то, что он только что прочитал)

              Приёмам работы можно обучить и обезьяну…


        1. konshyn
          22.03.2018 11:04
          -1

          Я не понимаю какое отношение трассировка лучей имеет к разработке графического движка

          Графический движок может быть как real-time, так и нет.


          1. AllexIn
            22.03.2018 12:14

            Не real-time движки обычно графическими движками не называют, это обычно «системы рендеринга» или «рендер» в просторечии.
            Ну и это вообще другая область разработки, другие техники и другие проблемы.


            1. Marui
              22.03.2018 12:44

              Horizon-Based Ambient Occlusion (HBAO): Considers the depth buffer as a heightfield, and approximates ray-tracing this heightfield
              GPU Ray-Casting for Scalable Terrain Rendering


              1. AllexIn
                22.03.2018 12:47

                Техник много разных. Имею ввиду популярные и актуальные.


        1. alex_zzzz
          22.03.2018 23:01
          +1

          Я писал много движков, с нуля. Писал собственную мат либу. Но я не смогу ответить на вопрос, как найти пересечение прямой и плоскости.

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


          1. Найти точку на земле или другой поверхности, на которую игрок указывает прицелом или курсором мыши. Это в чистом виде поиск пересечения луча/прямой с плоскостью.
          2. Есть луч и треугольник. Определить, проходит ли луч сквозь треугольник, и если да, то в какой точке. Ищем точку пересечения луча с плоскостью треугольника. Если таковая есть, проверяем, она внутри него или снаружи.
          3. Есть полигон и плоскость. Определить, пересекаются ли они, и если да, то разрезать полигон плоскостью на две части. По ходу решения потребуется поиск точки пересечения отрезка/прямой и плоскости.

          Ну так-то ответ очевиден, уравнение прямой + уравнение плоскости.

          Не обязательно. Обычно намного удобнее всё представлять точками и векторами и решать задачи через свойства скалярного и векторного произведений и свойства треугольников и параллелограммов (привет школьной геометрии, про которую все думали, что никогда не пригодится). Прямую удобно представлять как произвольную точку на ней и единичный вектор направления. Плоскость ? как произвольную точку на ней и единичный вектор нормали. Либо как нормаль и расстояние от плоскости до начала координат (эти же значения используются и в уравнении плоскости).


          Если для решения задач писать уравнения, то 1) для 2D и 3D они разные; 2) в коде появляются магические трёхэтажные формулы, по которым хрен поймёшь, что и как они считают.


          А вектора и точки остаются векторами и точками и в 2D, и в 3D. Решения многих задач универсальны и записываются короче.


          Например, как найти расстояние от точки P до произвольной прямой? Если прямая задана точкой O и единичным вектором направления D, то искомое расстояние ? это тупо модуль векторного произведения (O, P) и D, просто исходя из школьной формулы площади параллелограмма и свойств векторного произведения. Решение в одну строчку:
          cross(line.origin - point, line.direction).magnitude


          1. AllexIn
            23.03.2018 01:15

            Неужели никогда не приходилось это делать?

            ТАк о том и речь, что приходилось. И мильён раз. Но реализовал один раз в либе и забыл.
            Ну по факту не один раз, потому что далеко не одна либа была написана. Но сути не меняет.


    1. Marui
      22.03.2018 09:49

      Это тупа вопросы с экзамена по курсу компьютерной рафики любого ВУЗа ЕС или США. Так что да, знают.


  1. vladon
    22.03.2018 20:44

    А как же ТОП-0 по C++: «Почему нельзя бросать исключения в деструкторе?»


    1. konshyn
      22.03.2018 23:45

      Можно. Рекомендация звучит несколько иначе: «Не позволяйте исключениям покидать деструктор»