Przejdź do głównej zawartości

Job interview: software developer

We now have two or three generations of software developers who got their first job (or any next job) by correctly answering the question: "what will be the output of this code?". As we possibly did not have a better idea what to ask a candidate about, this might have been a satisfactory question one generation ago. Is it OK, from the point of view of the recruiting entity and the candidate, to ask the same question today? I would gladly replace the conventional list of questions:
  • what will be the output of this few lines of code?
  • what will be the size of this structure in memory?
  • what is wrong with this code snippet?
with questions more relevant to daily developer's tasks, like:
  • try to refactor this code snippet
  • look at this class; how would you add a unit test to test this function?
  • after running this program, explain why it prints this output
While the former questions test something, they are not even close to problems that a developer faces daily. On the contrary, seeing how someone attempts to test a function in a class that was not developed with TDD may give us much more insight to their programming abilities.

Ideally, these questions would be answered by using a simple compiler and editor during the interview. Developers don't program on paper in their jobs (at least no longer). If they want to learn something about the traits of the code, they lean on the compiler (for example, print size of a structure, instead of calculate it in your mind).

As you could have infer from this short opinion, I am also not in favor of automated, on-line coding tests. They are not done on paper, which is good, but they focus too much on exact answer, oftern numeric, instead of other important abilities, such as writing concise code.

Komentarze

  1. Hi, Piotr, thanks for the post.

    My opinion is that companies lean on the "book knowledge", because the other skills you mention are so rare that most developers would just fail this kind of test.

    Shameful as it is, most of us don't know how to refactor. Most of us don't know how to write unit tests and most of us don't know how to write clean code (by the way, sometimes the engineers that do the hiring don't have the necessary skills themselves). There aren't that many developers (when compared to demand) on the market and companies keep hiring. So maybe companies don't want to recruit based on tests that will be failed anyway?

    OdpowiedzUsuń
  2. That's an interesting observation. But if it's true, it is a closed loop, unfortunately - no asking about UT, in fear that they would fail => no demand for this skill on the market => no point in learning about UT, because it is not how you get a job - and the cycle continues. But regardless of that point of view, I think a couple of code exercises - not necessarily involving refactoring or UT - done on a computer would tell the recruiter more about the candidate than writing code on paper. I did not mention it in the post, but I think a good developer must be able to engage into, as I would call it, a dialogue with the computer (or compiler). I try this and the compiler tells me this. I change that and when I execute I get something else. Small steps, interaction and focus on what's being done.

    OdpowiedzUsuń

Prześlij komentarz

Popularne posty z tego bloga

Unit Testing code with IO file operations (in Python)

We may often come across a piece of code that was written without Unit Tests at all. In addition, the piece of code may be dealing with IO like file writing and reading, which makes it more difficult to Unit Test it when we are trying to refactor and modify. Let's suppose the code in question looks like this:

def writeInitialsToFile(filename, name, surname):
    initials = name[0] + '.' + surname[0] + '.'
    with open(filename, 'w') as file:
        file.write(initials)

def readInitials(filename):
    initials = None
    with open(filename, 'r') as file:
        initials = file.readline()
    return initials

A straightforward and bad idea would be to write a couple of Unit Tests that make use of a real file and simply test the reading and writing. Is therea a better way to test this code?

First of all, we need a way to replace the real file with something else. For both reading and writing we will now have a couple of functions, one that expects a stream fo…

Piotr's Less Obvious Advice on Google Mock: State maintenance

Google Mock provides several ways to maintain state inside mock objects. One way of implementing state maintenance is with SaveArg. Consider the following example.

We have a class Configurator, which allows a caller to set and get values of a parameter:

class Configurator
{
    public:

    virtual ~Configurator() {}

    virtual void setParamX(int n) = 0;
    virtual int getParamX() = 0;
};

And we have a class Client that calls Configurator's methods and it also has a method incParamXBy, that can be used to increase the current value of paramX by a certain value.

class Client
{
    public:

    Client(Configurator & cfg);
    virtual ~Client() {}

    void setParamX(int n);
    void incParamXBy(int n);
    int getParamX();

    private:

    Configurator & _cfg;
};

incParamXBy internally calls setParamX and getParamX on Configurator:

void Client::incParamXBy(int n)
{
    _cfg.setParamX(_cfg.getParamX() + n);
}

Let's assume that the initial value of paramX is A and that we want to increase paramX by…

Piotr's Less Obvious Advice on Google Mock: Returning new objects from a mock

Google Mock provides a way to return newly created objects from a mock method. Suppose we have a  Generator class that is supposed to generate new objects when createNewRecord method is called:

class Generator
{
    public:
    virtual ~Generator() {}
    virtual Record * createNewRecord() = 0;
};

...and suppose we want to mock this class:

class MockGenerator : public Generator
{
    public:
    MOCK_METHOD0(createNewRecord, Record * ());
};

Suppose the caller class Client has run method defined as follows:

void Client::run()
{
    for(int i = 0; i < 3; i++)
    {
        rec_tab[i] = gen.createNewRecord();
    }
}

We want the mock to return a pointer to a new object each time createNewRecord is called. This is how we can express this in the test code:

TEST(ClientTest, CanRun)
{
    MockGenerator gen;
    Client c(gen);

    EXPECT_CALL(gen, createNewRecord())
        .Times(3)
                 //this is equivalent of returning new Record(1,2,3)
        .WillOnce(ReturnNew<Record>(1,2,3))
        .Will…