Results 1 to 10 of 10
  1. #1
    Join Date
    May 2011
    Posts
    95

    Job Interview at a Game Company in a Few Days (Need Some Advice)

    Hello everybody!

    So I am a recent Computer Science in Digital Gaming and Simulation college graduate and have applied to several gaming companies. A few weeks ago I was contacted by a massive gaming company to do a coding test where I needed to write a game in C++ in a set amount of time. I did this, turned it in, and then was contacted again to do a phone interview.

    This is where I am terrified. The recruiter explained to me that I would need to perform a C++ exam while on the phone. She said and I quote, "... although it covers basic C++, it is extremely extensive. Please study and brush up on C++ because we want to weed out those who are making mistakes or don't know C++ very well". The test is version agnostic (meaning it doesn't matter whether it is C++10 or C++11).

    So, I am thoroughly worried. I was wondering if there were any guys here that might be C++ Software Engineers in the industry that might give me some direction as to what I definitely need to go over. I have been programming mainly in C# since my school never offered C++, but I have written quite a bit on my own in C++.

    - Should I go over design patters? For example, how exactly singletons should be used or maybe things like the Factory design pattern?
    - Should I spend a lot of time trying to understand in which order destructors get called in a multiple inheritance situation?
    - Are templates something I should know forwards and backwards before going into this interview?
    - Should I be focusing on understanding syntax for function pointers, virtual functions, pure virtual functions and abstract classes, or memory allocation (malloc and such)?

    I just feel so overwhelmed. This job is one I want really bad so I'm reaching out to as many resources as I can to try and figure out what it is exactly that I need to do to prepare myself. Pretty much the next 80 hours of my life will be spent in front of a computer studying. I'm going over the 3DBuzz Software Engineering videos from start to finish in C++, but if anybody has other suggestions too, any help is appreciated.

    Thank you all so much for reading!

    Josh

    PS. Right now I am stuck in the middle of Canada and have no access to books or even a book store. Pretty much anything I can look at will have to be online.

  2. #2
    Join Date
    Jun 2003
    Location
    Trier, Germany
    Posts
    1,350
    First of all: Relax. They're not going to drop you because you don't know the syntax intricacies of C-function pointers (and if they do, that's probably not a place you'd want to work at ).

    Phone interviews don't go too deep. Their sole purpose is to determine whether a candidate is worth inviting to a real interview. They usually don't ask really tough questions here, but focus on the basics. Remember that an interview always works both ways: If you find the phone interview questions are too hard for you, that is a certain indication that your skills are not up for the job. Even if you could manage to get hired afterwards, you would find yourself in a job that expects way more of you than you can deliver. So don't put too much pressure on yourself here. If you flunk the interview, that is only an indicator that your current experience does not match their requirements. Be glad that you figured it out in such a painless way and consider applying again in a few years.
    Embrace that attitude and you will find that most of the pressure and stress will already fade.

    That being said, of course there is no harm in preparing properly for an interview.

    Pretty much the only thing that matters is that you get the basics right. What can be considered 'the basics' varies significantly from job to job, but usually the job description gives all the hints you need to figure this out. Since you asked about C++ programming in particular, here's some of my expectations when interviewing:

    For example, you should understand polymorphism. Understand the concept behind it and have at least a vague idea of how C++ implements it. You don't have to be able to draw a vtable memory layout from scratch (although it does not hurt if you can do that ) but you should be able to explain the concept in a concise way without sounding like you only ever heard about it in a programming 101 lecture. You should also be able to identify the key issues arising when implementing polymorphic types in C++ (in particular stuff like virtual destructors, slicing, value types vs. polymorphic/reference types). This goes for all basic language features that you use on a day-to-day basis.

    You should know the basic language idioms. If you cannot write a copy assignment operator without hesitation, you clearly haven't worked with the language a lot. Know how const correctness works. Know RAII. Know when to use inheritance and when to prefer composition. All of this stuff that might not be in the first C++ book you read, but certainly in the second.

    You should know the libraries and tools. For C++ in particular, you should know the basics of the STL. Don't memorize the interfaces, but know for example how to use vector to solve a simple problem. Know the difference between a std::set and an unordered_set. Know a little bit about popular libraries like Boost. Know how to use a debugger to diagnose and fix problems. Not all of this is equally important for a specific job. For example the games industry has a reputation to favor hand-written libraries over the STL or Boost, but knowledge here still shows that you have used the language in a real world environment before.

    Know how to code well. This is somewhat language-agnostic and it certainly isn't as important for a junior position as it is for an experienced developer. But even from simple code samples it is quite easy to tell the level of professional experience that the author has. Know how to structure code correctly. Know how to design and enforce invariants. Know how to detect and report errors correctly. This is not as essential as the previous items, but once you figure this out, you will rock pretty much any interview. The main thing interviewers want to avoid is ending up with someone that is causing them more work than they are getting done. Show that you know your way around code, and they will be happy. Even if you are not that good at this yet, your main goal in your first job should be to become better quickly. If you have the feeling that the job is not helping you move forward in this regard: Get another job, asap. I'm not kidding.

    Know your domain. If your position is systems programmer, know how virtual memory works and how it affects your program. Know the internals of the operating system and know at least the basics about the hardware. If your position is graphics programmer, know shaders and shading languages. Know the basics of how a GPU works and how software interacts with it. If the job requires multithreading experience, know the threading primitives and how to use them. Know what data races are, how they emerge and how they can be diagnosed. This is very specific to the job and almost impossible to prepare for. But you should know for yourself which domains you know well and which you don't and communicate that clearly. The interviewer will appreciate it.

    Some of the things you do not need to know:

    Deep template shit, unless explicitly required. It's nice if you can explain what SFINAE is and how to use it, but unless the position expects you to write crazy template libraries, no one will ever ask about this. Know the basics but don't bother with the deep stuff unless you really mean it (it's quite fun though, so give it a try some time ).

    Stupid language corner cases that don't matter in the real world. If you class hierarchy is so fucked up with virtual inheritance that you cannot see which class gets constructed first, the problem is the class hierarchy and not the programmer who cannot make sense of it. And I'm willing to defend that position in an interview any day. It's very easy to construct complex scenarios in C++ where it's very hard to tell what's going on. This is not clever, it's stupid and unproductive. A good interviewer will never expect you to know this stuff by heart. If it comes up anyway, don't be afraid to point out if you think the example code is broken and (politely) request a rationale for crappy example designs. This only shows that you are able to distinguish good code from bad code, so don't be shy.

    Design patterns are an important tool for architects and developers, but don't overestimate their value in the real-world. Their most important use is that they allow to communicate certain concepts efficiently. But unless you are applying as an architect, no one should expect you to know every GoF pattern by heart. Understand why patterns are useful and that they are no silver bullet. Each pattern has advantages and drawbacks and only if used in the appropriate context do they make sense. Still, you should be able to explain at least one or two of the basic GoF patterns (pro tip: don't choose Singleton) thoroughly. It does not have to be Visitor, although you might be able to impress an architect if you get it right in an interview (but please only try it if you are really comfortable with this stuff).

    To wrap up this already overly long post: You already made it through the first stage of the interview, which means they already think that your skills are not too shabby. Trust your skills. Know the basics. Don't panic. Worst thing that can happen is that you leave the interview a smarter man.

    If you feel comfortable with it, it would be great if you would tell us how it went afterwards.

    Edit: Post #1337. Talking about symbolism...
    Last edited by ComicSansMS; 01-24-2014 at 01:32 PM.

  3. #3
    Join Date
    May 2011
    Posts
    95
    -----This post is a work in progress, please forgive formatting issues. I will resume working on this when I wake up-----

    Hey again ComicSansMS! Seriously if I get this job I'm gonna buy you something nice and send it to you lol! You've been just the most incredible help over the years I've been asking questions here. I've been studying non-stop since my post and have gone over topics that you mentioned, and topics from other forums. I've also done numerous online C++ exams. C++ is a lot more intense than I expected. My school only taught C# and Java in upperclassman courses and even the introductory C++ courses are taught as if the programmer had no control over memory and such. So over the past few days, injecting information about virtual tables and even basic concepts such as stack and heap allocation into my brain has been extremely challenging, but fun at the same time. More than once I've found myself going, "OHHHHHHH so that's why it works like that!", and then being extremely glad I found that article as it would have been embarrassing to go into the interview thinking in the way I had thought before. For example, I just realized that code shifted into a cout statement is executed from right to left. Why did my professors not mention that (rhetorical question).

    Anyway, what I am going to do here is write kinda of a "Study Guide" synopsis of everything I studied and everything I learned over the past few days Then, after my interview (which is in about 16 hours) I will post the results and what topics were discussed and which weren't. This way maybe other people who are in the same situation will have a single place with all of this information compiled together. I will start with your points but will probably go back and forth.
    I will only be typing the things I learned and did not know before the past few days. Please correct me if I'm wrong somewhere also! It will probably be too late for the interview but at least I will know better next time! I will pretty much be using the following code as example code for this post.
    Code:
    struct Weapon() { virtual void makeSound() { cout << " Default Sound " << endl; }
                               virtual void printName()   { cout << " Default Weapon " << endl; }
                               void Attack(){ // do something};
                           public:
                            int data; 
                            string name;
                           protected:
                           float damage;
                           private:
                           float speed;
    };
    struct Sword() : public Weapon{virtual void makeSound(){cout << "SHING! " << endl; }
                           virtual void printName(){cout << "Sword! " << endl; }
                           
                             
    };
    struct Bow() : protected Weapon{virtual void makeSound(){cout << "THKK! " << endl; }
    
    struct Axe() : private Weapon{}
    };

    Polymorphism

    • Vtables

    So, for every type in the program that has the "virtual" key word somewhere in its inheritance tree, a vTable will be created. The vTable is allocated usually in the first 4 bytes of the class,resides in the heap rather than the stack, and contains a map of addresses. The reason it is allocated on the heap, is because the compiler was unable to resolve a function call at compile-time and needs to dynamically decide which implementation of a function to call at run-time. There is only one vTable per type and all instances of a type share the same vTable. Also, only virtual functions appear in the virtual table. Below what each type's virtual table looks like.

    --------------------------------Virtual Function ----------------------------------------------------------------Points To
    Weapon ----------------------makeSound >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>(Weapon)mak eSound
    ----------------------------------printName >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>(Weapon) printName

    Sword ------------------------makeSound>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>( Sword) makeSound
    ---------------------------------printName >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>(Sword) printName

    Bow --------------------------makeSound>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (Bow) makeSound
    ------------------------------- printName >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>(Weapo n) printName

    Axe---------------------------makeSound>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (Weapon)makeSound
    -------------------------------printName>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>(Weapon printName

    When a virtual function is called, the vTable is referenced and the appropriate function is placed in a stack frame on the call stack.

    • The Four Types of Polymorphism

    ? - Parametric Polymorphism (compile-time)
    This type provides a means to execute the same code for any type and is implemented through the use of templates.
    - Subtype Polymorphism (Run-time)
    This gives us the ability to use derived classes through base class pointers and references. It happens at run-time through indirection via the virtual table. The compiler will locate the address of the function by dereferencing the correct pointer in the vTable.
    - Ad-Hoc Polymorphism
    Also known as overloading, it is the ability to give functions of the same name, so long as they have different signatures, different behaviors. An example would be of two functions called "add". One adds numbers while another concatenates chars.
    - Coercion Polymorphism
    Also known as implicit or explicit casting


    • Inheritance

    ?- Public Inheritance
    When Sword inherits from Weapon publicly, all access modifiers from Weapon remain the same. That is, name is still public, damage is still protected, and speed is inaccessible from Sword.
    - Private Inheritance
    When Axe inherits privately from Weapon, all public and protected members are accessible to Axe and become private. However, speed is still inaccessible to Axe.
    - Protected Inheritance
    When Bow inherits protectedly from Weapon, all public members become protected, protected members stay protected, and private members of Weapon are still inaccessible to Bow.

    Casting
    Should be avoided as much as possible in general.


    • Static Casting

    Consider this code:
    Code:
     Weapon * weap = new Bow
     //Bow * bow = weap  is illegal. Weapon is too general of a type. But as programmers, we know we made weap type Bow.
    Bow* bow = static_cast<Bow*>(weap); // So it is safe for us to do this.
    The compiler is not going to assume anything at all. It doesn't know, even if we hard coded it, which exact type we are going to use. It could be Weapon, Sword, Bow, etc. By creating a static cast, we are forcing the compiler to convert weap to the type of Bow at compile-time. This saves us costs at run-time. However, in this case using a dynamic_cast would be safer. Consider this code:
    Code:
     Weapon * weap = new Bow
    Sword* sword = static_cast<Sword*>(weap); // This compiles just fine!
    Even though the above code compiles, if I were to use "sword", the behavior would be completely undefined because we screwed up casting weap to something it shouldn't have been.
    • Dynamic Casting

    - Happens at run-time. Essentially it will try to cast the object into the type specified.
    - Will not work without the presence of a vTable!!
    - The programmer must always check for the return type before invoking a function from an object that has been dynamically casted. Consider the following code.
    Code:
     Weapon * weap = new Bow
     Bow* bow = dynamic_cast<Sword*>(weap); 
     if(bow) // always check!!
    {
       bow->makeSound();
    }

    • Reinterpret Casting

    - Happens at run-time.
    - Forces the compiler at run-time to reinterpret the casted data as a different data type. This is useful in game programming when handling save states (as I have read). Consider the following code
    Code:
    Sword sword;
    sword.data = 10;
    Sword* swordptr = &sword;
    
    int * intptr = reinterpret_cast<int*> (swordptr);
    
    cout << *intptr; // Will print 10, as the Sword data is now being treated as an int, accessing the values as we would an int                             //  array.

    Memory Management

    - What is the difference between stack memory and heap memory?
    The stack stores all of the information about function calls and local variables. At compile time, a set amount of memory determined by the needs of the program is set aside for the stack. While the application is running, the stack's allocated size does not grow! Heap memory however, is shared with the Operating System. It is used for dynamic memory allocation and can grow in allocated size.
    - Where are memory leaks caused, on the stack or on the heap?
    Memory leaks happen on the heap. Anything that we allocate on the heap, we are responsible ourselves for the deallocation of said memory. Memory allocated on the stack is automatically deallocated.
    - If we fill a buffer past its capacity, why don't we just allocate extra memory on the end?
    This is because the buffer was assumed to be created on the stack. Since at compile-time, extra space was not accounted for and there is other important information in that location such as the frame pointer, source address, destination address, etc. - Why does buffer overflow cause the whole program to crash?
    We try to go back to the caller, but the address of the caller has been overwritten by some garbage data that overflowed past our buffer.
    - Why can't we allocate an array with a non-constant index?
    Consider the following code:
    Code:
    std::cout << "Enter an array size";
    int arrSize;
    std::cin >> arrSize;
    int myArray[arrSize]; // Illegal!
    // Will not compile. Why the hell not????!?
    The stack must know at compile time how much memory to allocate on the stack.
    - Stack Specifics
    Each(single threaded process) gets its own stack. It is a contiguous block of memory at the process's address space. The stack consists of stack frame. Each stack frame contains parameters to a function, its local variables, and the data necessary to recover the previous stack frame. The stack contains high performance memory in terms of allocation time, but not so much in terms of access time. Its memory is almost always allocated with fixed limits.
    - Calling a function
    When a function is called, a "stack frame" for that function is pushed onto the stack, causing it to grow. When a function returns, it gets popped off and returned to the caller, causing the stack to shrink.
    - Caveats
    It is not possible to manipulate the scope of a variable once it is on the stack. The stack cannot grow once it is initialized.- Heap Specifics

    The heap is a large pool of memory used in dynamic memory allocation. The "new" keyword in C++ (also malloc in C) allocates memory on the heap. The applications heap size is not fixed and can grow or shrink during the lifetime of the application. Programmers have total control over how much memory he can use from the heap and how long the memory is allocated for.
    Assembly
    - What is it
    Assembly = machine instructions. C is a higher level language that gets translated into assembly.
    - Registers
    Extremely high performance memory located directly on the chip. General purpose register conventions EAX, EBX, ECX, EDX, used for performing operations on data.
    - Special Purpose Registers

    ESP: Stack pointer which points to the top of the stack. This register is manipulated by PUSH, POP, etc. The stack pointer can move its items as they are pushed on and popped off of the stack.

    EBP: Base Pointer, also known as the frame pointer. Local variables and parameters within a stack frame are referenced by their offset to EBP. EBP is fixed to that particular frame.

    ESI: and EDI: ESI = source information, EDI = destination instruction. These are uses to keep track when we’re calling functions and returning from them so we know where to go and where to come back.

    Constructors and Destructors

    - Constructors
    -Cannot be virtual
    -Copied objects must always be passed by reference or else the constructor will call itself infinitely.- Destructors
    - Are always called in reverse order of their corresponding constructors. For example,
    Code:
    
    
    Code:
    void Foo()
    {
           classA A;
           classB B;
           // B gets destroyed first.
           // A gets destroyed second.
    }


    - Virtual Destructors
    - Consider the following code:
    Code:
    
    
    Code:
    class Base
    {
             Base();
             ~Base();
    };
    
    class Derived
    {
           Derived();
           ~Derived();
    };
    int main()
    {
        Base * base = new Derived;
    }
    
    // The Base constructor gets called.
    // The Derived constructor gets called.
    // The Base destructor gets called.
    In the above code, the compile-time type of base is Base, but the run-time type is Derived. Because of the "new" statement, it knows to create a Derived object. Upon deletion however, Base is too general of a class to determine which destructor of any derived classes to call. Therefore, it only calls the Base destructor. To fix this, we only need to make the destructor virtual.

    It is important to note that with normal virtual functions, we only get the most specific implementation of the function when it is called. With virtual destructors, however, we go all the way up the chain.

    Like all tools, it should only be used when needed; keeping in mind that adding any virtual function will cause a vTable to be created - adding 4 bytes of memory to the size of the class along with additional overhead.

    - Copy Constructors
    - Shallow
    Simply does a bitwise copy of all of the values of an object
    Code:
    Sword sword;
    Sword sword2(sword);
    There is an issue with this though. Consider this code:

    Code:
    struct Player
    {
        Sword * sword;
        int playerId;
        Player(){ sword = new Sword;}
        ~Player() { delete sword;}
    };
    int main()
    {
       Player player;
    // Just to create new scope
         {
              Player player2(player);
         }
    }
    In the above code, we have some seriously unintended behavior( hopefully unintended, anyway). First, Player begins to be allocated on the stack until we reach the Sword pointer. The pointer gets allocated on the heap. When we try to copy player into player2, we start off just fine by allocating the playerId on the stack. The problem occurs when player2 receives a copy of the pointer itself. This means that both player and player2's sword pointers are pointing to the exact same memory address. Sure at first this may not seem all that bad, but leaving the scope that player2 is in triggers Player's destructor.

    We can already see that this is indeed very bad. It means that sword is going to be deleted and freed from the heap!! Now player.sword is pointing to the same memory address which no longer has a sword! When we exit player's scope and player.~Player() is called, player will delete whatever is at that address!! On windows, this will likely result in a debug assertion failed error, or a corrupted heap error.
    - Deep
    - Consider the following code

    Code:
    struct Player
    {
        Sword * sword;
        int playerId;
        Player(){ sword = new Sword;}
       Player(const Player &original) 
    {
       playerId = original.playerId;
       sword = new Sword( *original.sword);
    }
        ~Player() { delete sword;}
    };
    int main()
    {
       Player player;
    // Just to create new scope
         {
              Player player2(player);
         }
    }
    Now instead of player2.sword pointing to the exact same address as player.sword, he now has his own sword.


    Const Correctness

    - Pointers
    Code:
    // Poor Programming Example
           int number = 10;
           int badNumber = -9999;
           int * ptr = & number;
    // Both below expressions are valid. Memory address may be changed, along with the "pointed to" variable's value.
            ptr = &badNumber;
           *ptr = 255;
           std::cout << "badNumber address" << &badNumber << "\n";
           std::cout << "ptr address" <<  ptr;
           std::cout << "badNumber value" <<  badNumber << "\n";
           // badumber Address = 009EFA84
           // ptr Address      = 009EFA84
           // badNumber value  = 255
    //---------------------------------------------------------------------------------
    // Const - Correct Programming Example
           int number = 10;
           int badNumber = -9999;
           int * const ptr = & number;
           // The value of the variable pointd to by ptr may be changed.
           *ptr = 255;
           // ptr = &badNumber is not possible because the address that ptr points to is constant.
           std::cout << "number value " << number << "\n";
           // number value = 255
    //---------------------------------------------------------------------------------
    // Const - Correct Programming Example
           int number = 10;
           int badNumber = -9999;
           const int * ptr = & number;
           // The address that ptr points to may be changed.
           ptr = &badNumber;
           // *ptr = 255 is not possible because the value of the variable pointed to by ptr is constant.
           std::cout << "ptr value " << *ptr << "\n";
          
           // ptr value = -9999
    //---------------------------------------------------------------------------------
    // Const - Correct Programming Example
           int number = 10;
           int badNumber = -9999;
           const int * const ptr = & number;
    // Neither the address of ptr, nor the value of the variable that ptr points to may be changed.
    - Functions

    Code:
    // Not Const Correct example
    float GetArea(float &x, float &y)
    {
           float area = x * y;
    // accidental typo that would be very 
    // difficult to find given that its error will only be apparent at runtime.
           x = 2; 
           return area;
    }
     
     
    int main()
    {
           float x = 10; 
           float y = 20;
           float area = GetArea(x, y);
           std::cout << x << " * " << y << " = " <<area; // Will print 2 * 20 = 200. This is obviously incorrect.
           system("PAUSE");
           return 0;
    }
    // Const Correct example ----------------------------------------------------------------
    float GetArea(const float &x, const float &y)
    {
           float area = x * y;
    // 'x = 2' would produce a compiler error, preventing eroneous runtime errors from happening.     
           return area;
    }
     
     
    int main()
    {
           float x = 10; 
           float y = 20;
           float area = GetArea(x, y); // Will always yield predictable results.
           std::cout << x << " * " << y << " = " <<area; 
           system("PAUSE");
           return 0;
    }
    Placing const after a function prototype will indicate that no class variables will be changed in the function. Const functions cannot call functions that are not constant.

    Code:
    class classC
    {
    public:
           classC(){}
           // Only outputs values. Class variables will not be modified.
           void output() const;
           // Cannot be called from output() because doSomething is not constant.
           void doSomething();
    private:
           int n;
    };


    RAII(To Be Continued...)

    Exception Safe Assignments (To Be Continued...)

    Design Patterns (To Be Continued...)
    Last edited by frostbytes89; 01-28-2014 at 03:31 AM.

  4. #4
    Join Date
    Jun 2003
    Location
    Trier, Germany
    Posts
    1,350
    Some small-ish corrections after a hasty read:

    Quote Originally Posted by frostbytes89 View Post
    The vTable is allocated usually in the first 4 bytes of the class,resides in the heap rather than the stack, and contains a map of addresses.
    Don't confuse the vtable with the vptr. The vptr resides at the beginning of the class (which could be on the stack or anywhere else) and points to the actual vtable (which never resides on the stack).

    There is only one vtable per class type, but each object of that class has its own vptr pointing to it.

    Note that the vtable is only one technique for implementing runtime polymorphism. It's very popular and all popular C++ compilers use it, but there are other techniques that allow implementing identical behavior. In particular, the standard does not require an implementation to use vtables.

    The reason it is allocated on the heap, is because the compiler was unable to resolve a function call at compile-time and needs to dynamically decide which implementation of a function to call at run-time.
    This is only somewhat right. You need an indirection to make the virtual dispatch kick in (either through a pointer or reference), but the object could still live on the stack. Consider:

    Code:
    Bow bow;
    Weapon& weap = bow;
    weap.makeSound();   /// prints "THKK!"; weap still refers to an object of type Bow!
    Weapon sliced = bow;  /// makes a copy of bow into a Weapon; sliced refers to an object of type Weapon
    [*]Dynamic Casting[/LIST]
    - Will not work without the presence of a vTable!!
    More specifically: Will not work without RTTI. In general makes only sense for polymorphic downcasts (base class to derived).

    Pro tip: If you find the need for downcasting a lot, that usually indicates a design flaw.

    - The programmer must always check for the return type before invoking a function from an object that has been dynamically casted. Consider the following code.
    Unless you dynamic_cast to a reference type, in which case it will throw an exception if the cast fails. This is often preferable.

    Code:
     Weapon * weap = new Bow
     Bow& bow = dynamic_cast<Bow&>(*weap);
    - Why can't we allocate an array with a non-constant index?
    [/B]Consider the following code:
    Code:
    std::cout << "Enter an array size";
    int arrSize;
    std::cin >> arrSize;
    int myArray[arrSize]; // Illegal!
    // Will not compile. Why the hell not????!?
    The stack must know at compile time how much memory to allocate on the stack.
    Note that this is an arbitrary limitation of the language and not a fundamental technical limitation of the stack. For example, in C99 this is allowed.

    [/B]Each(single threaded process) gets its own stack.
    Better: Each thread gets its own stack.

    Code:
    int main()
    {
        Base * base = new Derived;
    }
    
    // The Base constructor gets called.
    // The Derived constructor gets called.
    // The Base destructor gets called.
    Well, strictly speaking no destructor gets called since you leak the object

    Copy Constructors
    Typical follow-up question: Does it make sense to have both a virtual destructor and a copy constructor in the same class?

    Const Correctness
    Also note that non-const references do not bind to unnamed temporaries. Here's why.

  5. #5
    Join Date
    May 2011
    Posts
    95
    Thank you for the corrections!! I will include those corrections as quotes in my final edit after I reformat and complete the rest. I'm still working on learning the other things (especially design patterns). So basically here is what happened. I had the phone interview and socially I think it went very well. When it came to the technical test though, I felt like I had bombed it. I am reluctant to say the exact questions as I am not sure if it was confidential or not (probably was), but I think I can say this much.

    The exam had (almost) nothing that I studied. It was a document similar to word pad that I had to type into. There were 4 questions and 3 were writing functions to implement various tasks and the last was a "What is wrong with this code" type question.I psuedo-coded 3 of them and then wrote down all of the things I saw wrong with the code in the 4th one. I just froze I guess, especially when the tasks I was supposed to implement just weren't things I did often. For example, if I ever need to do file IO, I just look up the syntax and go from there. There was no time for that here though. The problems were so simple though, it was just syntax I couldn't remember.

    Surprisingly though, they actually called me to do an in person interview!! They are flying me down too! But it's still scary, because I'm flying down with several other candidates. Apparently, for the interview I will be coding "all day" and my code will be evaluated. So, I have a bit more confidence but this is the important part and the final stretch. I know that the guy said I should really know design patterns and "practical coding".

    So, it is looking like I am going to be competing with these other guys in an all out coding brawl. I have no idea who I am up against, how out-classed I am, or what I should study. I feel like I now have a good solid foundation in terms of how things work at ground level, so should I be practicing algorithms now? Should I be doing problems like on Project Euler? Learn more theory?

    It would really help if I had any peers who knew C++ but I'm all on my own lol. My university taught only C# and Java so I have nobody close to do code reviews, give advice, etc. So any help as always is greatly appreciated . At this point I literally feel like I'm just shooting darts in the dark. This is probably one of the most important moments in my life and I want to do everything I can to be prepared.

  6. #6
    Join Date
    Jun 2003
    Location
    Trier, Germany
    Posts
    1,350
    Congratulations on passing the phone interview!

    For the on-site interview it is certainly good to prepare with some programming training. I wouldn't focus too much on theory here, because eventually you will have to write code, so that should be your priority. A difficult thing is of course always finding nice practice problems. Personally, I wouldn't recommend problem sites for this, as they are often too narrow in scope.

    For example, Project Euler puts the emphasis on mathematical problems. The solution to the problem lies not in engineering the program code in some clever way but in identifying a certain mathematical property that makes the problem easier to solve. Same thing for programming contest sites like ICPC. They usually focus on optimization algorithms like flow-optimization in graphs. Those algorithms are useful to know, but they might not help you much in an interview for a job in the games industry (and frankly, unless you already have a solid background in algorithms you might have a hard time learning them on short notice ).

    My advice would be to rather focus on something that is close to what you are applying for. For a game industry job, that probably means building a small game. Take into account the feedback you got from the earlier interview stages. For example you mentioned Design Patterns a few times. Try to write your code in a way that complies with the guidelines that motivated the introduction of Design patterns (refer eg. to Chapters 1.6 and the case study in Chapter 2 of the GoF book). With these guidelines in mind, you should be able to already identify a bunch of places in your code where patterns might help makes things easier (or places where you have used subconsciously used a pattern without identifying it as such). That way you will be able to experience how these concepts play out in the real world instead of just drooling over the theory. Take their advice to focus on 'practical coding' seriously.

    Similar advice for algorithms: At a job like this, people probably won't care if you can do a complexity analysis for QuickSort from scratch. What they do care about is that you can identify problems in the program that might be expensive to solve and be able to solve them efficiently. Consider for example collision detection in a game: Naive algorithms quickly leave you with a punishing O(N^2) complexity for N objects. An algorithmically smarter approach might be to organize data in a tree based on their position in the world which can reduce that to a much more manageable O(N * lg N). Even if you are right now not able to implement something like this from scratch, the important point is that you are aware that the naive solution is crap and that better approaches exist.

  7. #7
    Join Date
    May 2011
    Posts
    95
    Hey ComicSansMS,

    I just wanted to take a moment to thank you I should have done this earlier but I was busy with moving and working so much that I haven't really been online! I flew to California for the on-site interview where they had myself and three other candidates write a multi-player via LAN game from scratch in front of like 20 people. All of our monitors were projected on giant screens so that the audience of lead engineers, managers, and principle engineers could observe how we three worked together as a team to finish the game. Our team was among the only teams they have brought in to actually finish the game. They ended up hiring all three of us I have since moved to Cali and have been working here ever since! I started in March. Its absolutely amazing how little I actually know about programming next to the guys who work here haha! But it is an amazing opportunity to learn and grow!

    I absolutely could not have made it there without your advice and mentoring. I know it seems minor but you basically helped me learn the true practical basics of C++ programming, things that my university never even touched on, within like 4 days of the interview. Had I gotten no response I might have gotten discouraged because where can you go that has a list of things that companies want you to know? I used a combination of your advice and information I had pieced together from various forums to study and it has paid off! Working at this company has been a dream of mine since I was very young, so thank you again so much for helping me get to where I want to be

    frostbytes89

  8. #8
    Join Date
    Mar 2005
    Posts
    930
    This is a great story!
    "I don't WANT to pet the chicken."

  9. #9
    Join Date
    Jun 2003
    Location
    Trier, Germany
    Posts
    1,350
    That is great news indeed. Congratulations, man!
    I'm glad it worked out for you so well and I wish you an awesome time at that new job!

    Getting the first engagement is always a particularly tough challenge and it makes me very happy that my advice was helpful in getting you there. I'm looking forward to playing lots of cool games with your code in it

  10. #10
    Join Date
    Mar 2011
    Location
    Turin
    Posts
    129
    I wish they want ask to do advancecrd c++ like metadata programmin usin templates....good luck!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •