The Limber Lambda

Desperately Seeking Senior

Posted in Object Orientation, Recruitment by Eric Smith on February 27, 2010

Recently I chatted about appropriate coding assessment questions for senior developers, and came to the conclusion that Solver was a little too demanding for someone to do in around twenty minutes (under pressure), so I replaced it with Quicksort.

My assessment now consists of three questions:

  1. Fibonacci.  In short, “print out” the first thirty terms of the Fibonacci sequence, any which-way;
  2. Quicksort.  Sort a simple list of names into alphabetical order, applying a crude (read: not very efficient) implementation of the Quicksort algorithm;
  3. University.  Code up a set of objects and/or interfaces that describe a simple domain model, illustrating structural relationships between the domain objects.

Here’s University:

image

At first glance, this would seem fairly easy.  The tricky bit comes in due to the fourth bullet point in the problem description: “a lecturer might also be a student”.  Now C# doesn’t support multiple implementation inheritance, and this problem calls for a design involving multiple inheritance.

I’m going to present my solution to the problem.  I need to stress though, that I’m not wholly satisfied with it because it involves a StudentLecturer type (you guessed it … a hybrid) which just doesn’t sit well with me.

In any case, this is a classic case of the Diamond inheritance pattern (see the Diamond inheritance problem), and this is how the relationships might look:

University

I’ve deliberately left Course out because it isn’t really central to the real problem, and as a result, just creates clutter.  Within the bounds of the description of this problem, this solution might be acceptable, but it’s pretty tightly coupled and promises to turn into a bit of a nightmare should we need to extend the orthogonal roles to more than just Student and Lecturer (although, off the top of my head, I can’t think of how).  Ideally though, this sort of mixin scenario is more suited to a dynamic language like Python that allows types to be defined at runtime.  Never-the-less, it makes for a worthy brain teaser when done using a statically typed language that only supports multiple interface inheritance.

All three questions comprising the assessment are required to be completed within an hour.  What I didn’t anticipate though, is the response to the questions.  After assessing twelve people, no-one has provided a satisfactory answer to University.  Is this because it’s particularly hard?  Are C# developers, in general, not as strong on the modelling front?  It’s a little perplexing.

About these ads

11 Responses

Subscribe to comments with RSS.

  1. Rob Fulwell said, on March 1, 2010 at 02:05

    Why not allow every UniversityMember object to contain two (potentially zero length) lists:
    1) Courses taught by this UniversityMember
    2) Courses attended by this UniversityMember

    The student/lecturer attribute can be determined at any time by querying those lists, or better yet, by using a UniversityMember class method which determines the object status for you. All of this is malleable at runtime (a student can become a lecturer and vice versa, at any time) without changing the object type.

    Anything specified in the ILecturer interface can be implemented by a Lecturer object with an associated object factory which takes a UniversityMember as a parameter.

    • Eric Smith said, on March 1, 2010 at 07:55

      @Rob – that’s definitely one solution. I’m definitely open to answers here, so the one I presented really is your typical “static OO modelling” version.

      Your proposed design loosens up the invariants somewhat, and you’d actually have to code up what’s necessary to maintain invariants. In particular, for e.g., one can’t have a student number if one doesn’t attend any courses, since by implication, not attending courses means that you’re not a student (which in itself leaves some questions – like there may be a period during which it’s legal for a student to not attend any courses?).

      In any case, provided I get a satisfactory answer and it’s sufficiently annotated to describe non-explicit idioms, I’m willing to give the candidate the benefit of the doubt.

  2. Ryan C. Moon said, on March 1, 2010 at 21:00

    Rob, would you accept code for #1 that said:
    print “0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 \n”;

    Just wondering at your tongue-and-cheek acceptability on these quizzes?

  3. Rob Fulwell said, on March 2, 2010 at 06:10

    Eric might accept that but this is shorter (PowerShell):

    $p = 0;$c = $i =1;$p;$c;while ($i -lt 29) {$c,$p=($c+$p),$c;$c;$i++}

    (Also, Ryan you have one too many terms listed.)

  4. [...] Posted in Algorithms, Development, Opinion, Recruitment « Desperately Seeking Senior [...]

  5. Adrian Hara said, on March 8, 2010 at 07:27

    Off the top of my head, wouldn’t a solution where we don’t actually have concrete classes like Student, Lecturer or StudentLecturer that derive from UniversityMember, but a UniversityMember and some Role-s instead work better? This way we could also have a JanitorLecturerRole or GymCoachStudentRole or whatever :) without complicating the inheritance too much.

    • Eric Smith said, on March 8, 2010 at 18:18

      Adrian – that’s the beauty of this question, there isn’t just one answer. How the question is answered reveals something about how the candidate thinks.

  6. Tor said, on April 5, 2010 at 16:47

    I think many would be confused by this question and wonder what it is you are looking for. What are the classes supposed to be used for?

    I would do something like the following pseudo-code, but I suspect it is not all what you want:

    Class Person:
    String name
    String studentID
    bool isLecturer
    Array(Course) courses

    Class Course:
    String courseID
    String courseName
    Person lecturer

    • Eric Smith said, on April 7, 2010 at 17:59

      Tor – as it so happens, it’s become fairly clear that pretty much everyone so far is “confused by this question and wonder what it is I’m looking for”. I’m now treating the responses as an indication of how a candidate thinks as opposed to a quantitative means of determining if the candidate “makes the bar”.

      At the end of the day, the idea is to produce something that “cleanly” represents the domain. The domain can be represented in different ways, some “purer” than others. Taking a look at your solution:

      Q: Is a Person a student?
      A: In our domain, no, but your solution suggests so.

      Q: Is a Person a lecturer?
      A: In our domain, no, but your solution suggests so.

      Ok, so let’s rename “Person” to “Student” … then:

      Q: Is a Student a lecturer?
      A: Not *necessarily*, but possibly. A pure design wouldn’t encapsulate anything in a student class that relates to a lecturer, because, .. well, a student isn’t a lecturer.

      So, in short, there are many practical solutions (yours being one of them), but they don’t necessarily cleanly represent the domain.

      Another criticism of your design: does a course “have” a lecturer? I’m a little uneasy with that semantic association. I would prefer: a lecturer presents one or more courses.

  7. Beau said, on April 11, 2010 at 22:33

    Here’s my thoughts for the University problem. Assuming the Lecturer is always a student (although maybe enrolled in 0 courses) makes it easier I think:

    class Person
    {
    public string Name { get; set; }
    }

    class Course
    {
    public Lecturer Lecturer { get; set; }

    public Student[] Students { get; set; }
    }

    class Student : Person
    {
    public Course[] CoursesEnrolledIn { get; set; }
    }

    class Lecturer : Student
    {
    public Course[] CoursesTaught { get; set; }
    }

  8. Florencio said, on August 15, 2010 at 22:50

    I took a shot at “University”. My solution is, each “Person” has a list of courses they are attending along with their role in that course. They can have multiple roles in a single attended course.

    It was an interesting challenge.

    public class Course
    {
    public int room;
    public string name;
    public Course(int room, string name)
    {
    this.room = room;
    this.name = name;
    }
    }
    public interface Role
    {
    string Name { get; }
    }
    public class StudentRole : Role
    {
    public string Name {
    get { return “Student”; }
    }
    }
    public class LecturerRole : Role
    {
    public string Name {
    get { return “Lecturer”; }
    }
    }
    public class JanitorRole : Role
    {
    public string Name {
    get { return “Janitor”; }
    }
    }

    public class CourseAttending
    {
    Course course;
    Role[] roles;
    public CourseAttending(Course course, Role[] roles)
    {
    this.course = course;
    this.roles = roles;
    }
    }
    public class Person
    {
    public string name;
    public CourseAttending[] coursesAttending;
    public Person(string name)
    {
    this.name = name;
    }
    }

    public void Main()
    {
    Person person = new Person(“John”);
    Course course = new Course(101, “WWW”);
    person.coursesAttending = new CourseAttending[] { new CourseAttending(course, new Role[] {
    new StudentRole(),
    new LecturerRole()
    }) };
    }


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: