CodingQuiz post-mortem


I developed Codingquiz in 2010. At that time, doing a coding test online was rather uncommon. A few sites existed but not as many as today.

I took some time off to develop the site. And as it happens quite often, when developing for oneself it’s easy to get over-motivated. This ended up in building a front-end library similar to Bootstrap, which didn’t exist at that time, plus a generic framework for creating Stripes based web projects (which was in the end too much “genericness”).

Implementation

I used Stripes a the web framework, together with MySQL and iBatis as the persistence layer. The core part of the service was the dynamic compilation and evaluation of interview questions. Question could be defined via a class stub. The backend would then fill in the user answer, compile the whole class, run the unit tests and send back the result to the front-end.

An example interview question looked like this:

package net.wenzelconsulting.telinterview.nonpublic.catalogQuestions.arrays;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import org.junit.Test;

// @Title:Reverse Array
// @Time:10
// @Level:0
// @Category:Data Structures
// @Description
// Implement a method that returns a new array where the order of elements has been reversed.
// For example:
// Input: ["a", "b", "c"] => Output: ["c", "b", "a"]
// @EndDescription
public class ReverseArrayWords
{
    // @Methods
    public static Object[] reverseArray(Object[] array)
    {
        // implement solution here
        return null;
    }
    // @EndMethods

    // @Solution
    public static Object[] reverseArraySolution(Object[] array)
    {
        if (array == null) return null;
        Object[] reversed = new Object[array.length];
        int index = 0;
        for (int i = reversed.length - 1; i >= 0; i--)
        {
            reversed[index++] = array[i];
        }
        return reversed;
    }
    // @Endsolution

    @Test
    // @UnitTestBegin:Test single reversion
    public void testReversing()
    {
        // @UTStatements
        Object[] array = new Object[]{"a", "b", "c"};
        Object[] reversed = reverseArray(array);
        assertEquals(3, reversed.length);
        assertEquals("c", reversed[0]);
        assertEquals("b", reversed[1]);
        assertEquals("a", reversed[2]);
        // @EndUTStatements
    }
    // @EndUnitTest

    @Test
    // @UnitTestBegin:Test large data
    public void testReversingLargeData()
    {
        // @UTStatements
        StringBuffer s =
                new StringBuffer(
                        "awerojwerpowjeropweijrweopjrweopjirweriojweropjwerjweproijwe" + 		
                        "porjiwepojweirojweporjwprojiweprjiweporjweoprjweprjiweoprjwpo" + 
                        "rjwopqjropqjweropweqjrqpwojropqwejq");
        s.append(s);
        s.append(s);
        s.append(s);
        s.append(s);
        s.append(s);
        Object[] array = new Object[s.length()];
        for (int i = 0; i < array.length; i++)
        {
            array[i] = String.valueOf(s.charAt(i));
        }
        Object[] reversed = reverseArray(array);
        assertEquals(s.length(), reversed.length);
        assertEquals("q", reversed[0]);
        assertEquals("j", reversed[1]);
        assertEquals("e", reversed[2]);
        assertEquals("a", reversed[s.length() - 1]);
        assertEquals("w", reversed[s.length() - 2]);
        assertEquals("e", reversed[s.length() - 3]);
        // @EndUTStatements
    }

    // @EndUnitTest

    @Test
    // @UnitTestBegin:Test double reversion
    public void testDoubleReversing()
    {
        // @UTStatements
        Object[] array = new Object[]{"a", "b", "c"};
        Object[] reversed = reverseArray(array);
        Object[] reversedDouble = reverseArray(reversed);
        assertEquals(3, reversedDouble.length);
        assertEquals("a", reversedDouble[0]);
        assertEquals("b", reversedDouble[1]);
        assertEquals("c", reversedDouble[2]);
        // @EndUTStatements
    }

    // @EndUnitTest

    @SuppressWarnings("deprecation")
    @Test
    // @UnitTestBegin:Test boundaries
    public void testNull()
    {
        // @UTStatements
        assertEquals(reverseArray(null), null);
        Object[] array = new Object[]{"a"};
        Object[] reversed = reverseArray(array);
        assertEquals("a", reversed[0]);
        array = new Object[]{};
        reversed = reverseArray(array);
        assertNotNull(reversed);
        // @EndUTStatements
    }
    // @EndUnitTest
}

Clients could fully self-manage their interviews. An interview consisted of questions. Each question had a set of unit tests attached that would evaluate automatically and based on the result of each test create a final score that the interviewer could examine (click on image).

Thumbnail

The interviewer could try the whole interview in a simulated run. The person taking the interview had the chance to try a few sample questions before taking the real exam in order to familiarize herself with the platform (click on image).

Thumbnail

Business

The initial feedback was almost always positive. Regarding the idea and the implementation. As mentioned above, this was before online testing became so prevalent in software developer circles.

My idea was that clients should use the site to create and publish their own tests, and I provide the service to make that work smoothly. However, it became quickly apparent that the real interest in those kind of services are the actual tests. And those are not easy to come up with. I never got fully involved or had the time to get to the next level. I let the site run for some years. I had a few sign-ups but in the end it was not worth my time. I sunsetted the site in 2014.

Subscribe to Human Intelligence Engineering
Explorations of human ingenuity in a world of technology.