The Limber Lambda

Eric Smith’s technical musings

Desperately Seeking Senior

with 11 comments

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.

Advertisement

Written by Eric Smith

February 27, 2010 at 5:01 PM

11 Responses

Subscribe to comments with RSS.

  1. 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.

    Rob Fulwell

    March 1, 2010 at 2:05 AM

    • @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.

      Eric Smith

      March 1, 2010 at 7:55 AM

  2. 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?

    Ryan C. Moon

    March 1, 2010 at 9:00 PM

  3. 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.)

    Rob Fulwell

    March 2, 2010 at 6:10 AM

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

  5. 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.

    Adrian Hara

    March 8, 2010 at 7:27 AM

    • 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.

      Eric Smith

      March 8, 2010 at 6:18 PM

  6. 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

    Tor

    April 5, 2010 at 4:47 PM

    • 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.

      Eric Smith

      April 7, 2010 at 5:59 PM

  7. 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; }
    }

    Beau

    April 11, 2010 at 10:33 PM

  8. 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()
    }) };
    }

    Florencio

    August 15, 2010 at 10:50 PM


Leave a Reply

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

Gravatar
WordPress.com Logo

You are commenting using your WordPress.com account. 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.