Лучший способ получить опыт работы в C ++ для работы в играх (из C #) [закрыто]

19

Я разработчик программного обеспечения, опыт работы с C # (5 лет опыта) наряду с несколькими другими языками.

Моя «работа мечты» - работа в видеоиграх в качестве разработчика.

Большинство работ требует знания C ++, которого у меня сейчас нет (за исключением некоторых основ).

Я посмотрел вокруг, и большинству крупных игровых компаний требуется что-то из 3-5 лет предыдущего опыта работы с C ++.

Мой вопрос - какой будет хороший путь, чтобы подняться до этого необходимого уровня опыта, исходя из C #?

Я подумал о некоторых возможных способах сделать это:

Получите больше знаний о C ++ из книг. Участвуйте в проектах с открытым исходным кодом, написанных на C ++. Как лучше всего изучать C ++ и иметь опыт работы с ним, особенно в игровой индустрии?

spaceOwl
источник
1
Спасибо, я проверю это. Хотя я не уверен, что это точно такой же вопрос, как я не новичок в программировании.
SpaceOwl
3
Никого не волнует, как и откуда вы получили свой опыт, или вам заплатили за это или нет. Если вы хотите иметь опыт работы с C ++, начните программировать на C ++.
Майк Земдер,
@liortal Repost: Смотрите также Какие хорошие советы для начинающих? (какой-то чудак удалил все мои комментарии в этой теме).
Бобобо

Ответы:

29

Как разработчик игры, моей главной проблемой при найме парня на C # было бы отсутствие знаний низкого уровня.

Итак, рассмотрим проект, в котором ваша работа влечет за собой низкоуровневую оптимизацию, например, реорганизацию структуры данных классов или переписывание кода, чтобы воспользоваться преимуществами SIMD-инструкций. Возьмите игру с открытым исходным кодом на C ++, оптимизируйте ее и опубликуйте увеличение частоты кадров в своем резюме.

Если бы я брал у вас интервью, я бы меньше заботился о C ++ в вашем резюме и больше о том, можете ли вы ответить на мои вопросы по C / C ++ / интервью низкого уровня. Я попробую ответить на некоторые стандартные вопросы интервью, с которыми у вас могут возникнуть проблемы (предупреждение: я не эксперт по C #):

  • Как классы C ++ расположены в памяти? Нарисуйте схему байтов. Включите указатели vtable и отступы / выравнивание переменных-членов. Как насчет производного класса? А как насчет класса с множественными производными?
  • Как происходит вызов виртуальной функции на низком уровне? Поговорим о сборочных операциях, таких как чтение значения в памяти и переход к адресу.
  • Знать о приведении в стиле C, static_cast и dynamic_cast между указателями на типы с различными отношениями наследования. Например, классы B и C являются производными от класса A. Что происходит, когда вы пытаетесь привести от A * к B * (или от B * к C *), используя эти различные приведения? (Я упоминаю, потому что я не думаю, что C # даже разрешил бы эти конкретные приведения.)
  • Почему страшно передавать вектор stl по значению, а не по ссылке? (Я упоминаю, потому что большинство типов в C # являются ссылочными типами, и поэтому в C # практически невозможно совершить такую ​​ошибку.)
  • Что значит для структуры или функции быть кеш-дружественным? Почему структура массивов может работать лучше, чем массив структур?
  • Понимать кучу, стек и статическую память. Если объект был назначен с новым, где он живет в памяти процесса? Как насчет локальной переменной? Глобальная переменная?
  • Что за утечка памяти? Каковы некоторые наилучшие практики, чтобы избежать их? (Я упоминаю, потому что нет удаления в C #!)
  • Как бы вы отладили сбой нарушения доступа к памяти? А что, если сбой произошел в какой-то промежуточной библиотеке, для которой у вас нет исходного кода?
Эрик Андерсандер
источник
1
Репост: я уже знаю, насколько полезно знать, где указатели vtable находятся в памяти, потому что я столкнулся с ошибкой, связанной с этим раньше . Но чем полезен второй вопрос? Как знание "операций на уровне сборки, таких как чтение значения в память" делает компетентного программиста на C ++?
Бобобо
Мое интервью Blizzard, посвященное стажеру в WoW UI, касалось пунктов 1, 2, 3 (в меньшей степени), 5 и 7. Он также задавал вопросы об отладке / тестировании (аналогично пункту 8). Я думаю, что этот ответ точно на месте даже в общем случае для компаний-разработчиков игр верхнего уровня.
Дин Найт
2
@DeanKnight Я не сомневаюсь в этом. Но я все еще хотел бы знать, как OP думает, что такой вопрос делает кого-то хорошим программистом на C ++ (первоначальный вопрос о том, как стать лучшим программистом на C ++), а не просто помогает кому-то помочь в интервью.
бобобо
2
Вы говорите скептически, бобобо, но ваша ссылка об ошибке указателя vtable является отличным примером того, как полезно знать внутреннее содержимое вызовов виртуальных функций. Рассмотрим похожую ошибку, в которой вместо нулевого указателя vtable это мусор . Одним из способов понять, что это мусор, было бы пройти через разборку вызова виртуальной функции и увидеть, как ваша программа уходит в никуда, вместо того, чтобы перейти к действительной таблице или действительному методу.
Eric Undersander
1

Что сказал Эрик. Я также добавил бы, чтобы избежать "нового", где это не обязательно. Это очень часто встречается в C #, но считается плохой практикой в ​​C ++ 11, а также медленнее, чем выделение стека, и более опасно, потому что вы должны вручную освободить его.

Я был бы также осторожен со старыми книгами, они преподают старые методы. Я лично предпочитаю надежные форумы / сайты, stackoverflow / isocpp.

Lufi
источник
Благодарю. Я искал более общие, более общие советы / рекомендации о том, что делать, а не языковые особенности для изучения.
SpaceOwl
«Избегать new» - это действительно не разумная рекомендация. Вы используете, newкогда у вас есть указатели. Если class Derived : Base, то это Base var = Derived();незаконно, но Base *var = new Derived();законно. Так что вам нужны указатели, чтобы заставить полиморфизм работать правильно, много.
Бобобо
Да, но вы можете использовать std :: unique_ptr для достижения полиморфизма и избежать использования пустого указателя (хотя у вас все еще будет новое ключевое слово в конструкторе unique_ptr)
Эрик Б,
Извините, я допустил ошибку в приведенном выше комментарии. Base var = Derived() будет работать , но он будет разрезан и, без вашего ведома, информация потеряна в var. Чтобы решить проблему нарезки, вы можете использовать указатели.
бобобо