Najlepszy sposób na zdobycie doświadczenia w C ++ do pracy w grach (pochodzącej z C #) [zamknięte]

19

Jestem programistą, mam doświadczenie w C # (5 lat doświadczenia) wraz z kilkoma innymi językami.

Moja „wymarzona praca” polega na pracy w grach wideo jako programista.

Większość zadań wymaga znajomości C ++, którego obecnie nie mam (oprócz niektórych podstawowych).

Rozejrzałem się i większość dużych firm z branży gier wymaga czegoś od 3-5 lat wcześniejszego doświadczenia z C ++.

Moje pytanie brzmi - jaka byłaby dobra droga, aby dostać się do tego wymaganego poziomu doświadczenia, pochodzącego z C #?

Pomyślałem o kilku możliwych sposobach:

Uzyskaj więcej wiedzy na temat C ++ z książek. Bierz udział w projektach typu open source napisanych w C ++. Jaki byłby najlepszy sposób na naukę języka C ++ i posiadanie na nim praktycznego doświadczenia, szczególnie w branży gier?

spaceOwl
źródło
1
Dzięki, sprawdzę to. Chociaż nie jestem pewien, to jest dokładnie to samo pytanie, ponieważ nie jestem początkującym w programowaniu.
spaceOwl
3
Nikt nie dba o to, skąd i skąd wzięło się twoje doświadczenie, ani czy zapłacono za to, czy nie. Jeśli chcesz mieć doświadczenie w C ++, zacznij programować w C ++.
Maik Semder
@liortal Repost: Zobacz także Jakie są świetne wskazówki dla początkujących? (niektóre dziwne usunęły wszystkie moje komentarze w tym wątku).
bobobobo

Odpowiedzi:

29

Jako twórca gier moim głównym zmartwieniem w zatrudnianiu faceta z C # byłby brak wiedzy na niskim poziomie.

Rozważmy więc projekt, w którym praca wymaga optymalizacji niskiego poziomu, takiej jak zmiana układu danych klas lub przepisanie kodu, aby skorzystać z instrukcji SIMD. Weź grę typu open source w C ++, zoptymalizuj ją i opublikuj wzrost liczby klatek na sekundę w swoim CV.

Gdybym przeprowadzał z tobą wywiad, nie dbałbym o C ++ w twoim życiorysie, a bardziej o to, czy możesz odpowiedzieć na moje pytania do rozmowy kwalifikacyjnej na niskim poziomie C / C ++ /. Zajmę się niektórymi standardowymi pytaniami, z którymi możesz mieć problemy (ostrzeżenie: nie jestem ekspertem w C #):

  • Jak układa się klasy C ++ w pamięci? Narysuj schemat bajtów. Dołącz wskaźniki vtable i dopełnianie / wyrównanie zmiennych elementów. Co z klasą pochodną? A co z klasą wielokrotnie pochodną?
  • Jak odbywa się wirtualne wywołanie funkcji na niskim poziomie? Mów o operacjach asemblacyjnych, takich jak odczytywanie wartości w pamięci i przeskakiwanie pod adres.
  • Wiedza na temat rzutowania w stylu C, rzutowania statycznego i rzutowania dynamicznego między wskaźnikami do typów o różnych relacjach dziedziczenia. Na przykład obie klasy B i C wywodzą się z klasy A. Co się stanie, gdy spróbujesz rzucić z A * na B * (lub B * na C *) przy użyciu tych różnych rzutów? (Wspominam, ponieważ nie sądzę, aby C # pozwalał nawet na te konkretne obsady).
  • Dlaczego przekazanie wektora stl przez wartość zamiast przez odniesienie jest straszne? (Wspominam, ponieważ większość typów w C # jest typami referencyjnymi, a zatem w zasadzie niemożliwe jest popełnienie tego rodzaju błędu w C #).
  • Co to znaczy, że struktura lub funkcja jest przyjazna dla pamięci podręcznej? Dlaczego struktura tablic może działać lepiej niż tablica struktur?
  • Poznaj stertę, stos i pamięć statyczną. Jeśli obiekt został przydzielony z nowym, to gdzie mieszka w pamięci procesu? Co ze zmienną lokalną? Zmienna globalna?
  • Co to jest wyciek pamięci? Jakie są najlepsze praktyki ich unikania? (Wspominam, ponieważ nie ma usuwania w C #!)
  • Jak debugowałbyś awarię naruszenia dostępu do pamięci? A jeśli awaria nastąpiła w bibliotece pośredniej, dla której nie masz kodu źródłowego?
Eric Undersander
źródło
1
Repost: Znam już użyteczność wiedzieć, gdzie znajdują się w pamięci wskaźniki vtable, ponieważ wcześniej natrafiłem na błąd z tym związany . Jednak w jaki sposób drugie pytanie jest w ogóle przydatne? W jaki sposób znajomość „operacji na poziomie zespołu, takich jak wczytywanie wartości do pamięci”, czyni kompetentnego programistę C ++?
bobobobo
Mój wywiad Blizzarda dla stażysty WoW UI dotyczył punktów 1, 2, 3 (w mniejszym stopniu), 5 i 7. Zadawał również pytania dotyczące debugowania / testowania (podobnie jak w punkcie 8) Myślę, że ta odpowiedź jest dokładnie na miejscu nawet w ogólnym przypadku firm tworzących gry na wyższym poziomie.
Dean Knight
2
@DeanKnight Nie wątpię w to. Ale nadal chciałbym wiedzieć, jak OP myśli, że takie pytanie czyni kogoś dobrym programistą C ++ (pierwotne pytanie dotyczy tego, jak zostać lepszym programistą C ++), a nie tylko pomagać komuś w przeprowadzeniu wywiadów.
bobobobo
2
Brzmisz sceptycznie, bobobobo, ale twój link na temat błędu wskaźnika vtable jest doskonałym przykładem tego, jak przydatna jest znajomość wewnętrznych wywołań funkcji wirtualnych. Rozważ podobny błąd, w którym zamiast vtable wskaźnik jest zerowy , to śmieci . Jednym ze sposobów na uświadomienie sobie, że to śmiecie, jest przejście przez dezasemblację wirtualnego wywołania funkcji i zobaczenie, jak twój program odejdzie w nicość, zamiast przejść do prawidłowej vtable lub prawidłowej metody.
Eric Undersander
1

Co powiedział Eric. Dodałbym również, aby uniknąć „nowego”, gdy nie jest to konieczne. Jest to bardzo powszechne w C #, ale uważane za złą praktykę w C ++ 11, a także wolniejsze niż przydzielanie stosu i bardziej niebezpieczne, ponieważ musisz ręcznie cofnąć przydział.

Byłbym też ostrożny ze starymi książkami, uczą starych praktyk. Osobiście wolę niezawodne fora / strony internetowe, stackoverflow / isocpp.

Lufi
źródło
Dzięki. Szukałem szerszych, bardziej ogólnych porad / zaleceń dotyczących tego, co robić, niż specyfiki języka do nauki.
spaceOwl
„Unikanie new” nie jest naprawdę rozsądną rekomendacją. Używasz, newgdy masz wskaźniki. Jeśli class Derived : Base, to a Base var = Derived();jest nielegalne, ale Base *var = new Derived();jest legalne. Potrzebujesz więc wskaźników, aby polimorfizm działał prawidłowo.
bobobobo
Tak, ale możesz użyć std :: unique_ptr, aby osiągnąć polimorfizm i uniknąć nagiego wskaźnika (chociaż nadal będziesz mieć nowe słowo kluczowe w konstruktorze Unique_ptr)
Eric B
Przepraszam, popełniłem błąd w powyższym komentarzu. Base var = Derived() działałby , ale zostałby pocięty na plasterki i, bez wiedzy ciebie, zagubione informacje var. Aby rozwiązać problem krojenia, możesz użyć wskaźników.
bobobobo