by Miguel de Icaza

Some folks have been asking what kind of interviews we conduct over email for hiring in the Mono team. We allow people to work remotely. To find out how well they can work independently away from our office we came up with some tasks that we give out on job interviews.

In my experience with hiring people at Ximian, the face-to-face interviews did not yield as good results as reviewing someone's existing track record and contributions or these programming exercises.

A resume, plus an interview when you ask the candidate to "implement XX on the whiteboard" and some trick questions have too many problems which are probably worth discussing some other day. In my experience these kinds of interviews that have been popularized in the industry are bad. They evaluate developers on all the wrong dimensions that you need to produce software.

Am posting here two of the interviews that we used in the past to hire for positions into the Windows.Forms group and the Mono VM engine. These interviews are typically conducted over two to three weeks.

A story that I find funny was when we did the Windows.Forms interview. Once I emailed back the applicants with the 2 week deadline, Andreia Gaita replied to me within 2 or 3 days. She was the first to reply, but thought that she was the last, and her code was great, did everything I requested (and if she gives me permission I can post her submission).

Andreia turned out of course to be a superb hacker, see her recent work on Mono/Mozilla integration.

The interviews follow.

These are not the interviews that we will use for Moonlight, but it will give you an idea of what kind of thing we do ;-)

Windows.Forms Interview

Remember: these interviews are designed to be answered at home during your afternoons when you get back from school/work and would usually take a few days.

* The Widget You must implement a small rendering engine for a small XML-inspired markup language, the language accepts: <p>...</p> To start paragraphs. Paragraphs in turn can contain the following: <b>...</b> Where the text ... is bolded. <i>...</i> Where the text ... is italicized <link>...</link> Where the ... is rendered as a link <blink>...</blink> The text should blink. The control must expose one property: string Markup { get; set; } Which allows the developer to programatically set the markup language, for example: m = new MarkupControl (); m.Markup = "<p>Hello <b>World</b>!</p>"; The control must also expose an event, so I can hook up whenever someone clicks on a link: delegate void LinkClicked (object sender, string link_text); So I can use it like this: m.LinkClicked += my_clicked; ... void my_clicked (object sender, string link_text) { Console.WriteLine ("The link {0} was clicked", link_text); } You must also provide a complete program that will run when I run it in Linux, and you must also exercise the property and the event, this would be nice to have: void my_clicked (object sender, string link_text) { Console.WriteLine ("The link {0} was clicked", link_text); ((MarkupControl) sender).Markup = "<p>This is the new text after clicking</p>"; } Extra points: when I use blink, you will have to refresh, bonus points if you avoid flicker by using double buffering, or by only repaining the area that has changed. I want a small and succinct implementation, but this is your opportunity to show that you can write *robust* code, so impress me. * Trick Question In our corlib implementation, in System/DateTime.cs we have a suboptimal implementation of the method "TryParse", we basically call Parse inside try/catch. Explain: * Why do I say that our solution is "suboptimal"? * What would it take it to make more efficient? * Why did the maintainer that wrote that code not do the more efficient thing? The trick question is: Why was the faster process not done in the first place. Explain.

JIT Interview

This interview was constructed by Paolo Molaro when we were hiring folks for the JIT. The developers that joined us have been fantastic, Mark and Rodrigo. They are working in adding the CoreCLR security (I blogged about Mark's work before) and the verifier to Mono (which we will need for Moonlight) and have also been doing many other needed tasks on the VM.

This interview should take a week to complete in your afternoons. Between 8 to 16 hours for someone not familiar with Mono. We figured that not everyone has time to allocate to this immediately, so we will wait until March 30th to review the applications. All of this can be answered by using the officially released Mono packages from: http://www.mono-project.com/Downloads Get the mono-1.2.3.tar.gz source code download. Feel free to ask any questions privately or in any Mono public forums. First Task: Extending the Mono VM Given the following program, change the mono JIT to intercept the Datum.Add () function and implement it internally with a SSE instruction so that the additions happen in parallel. Datum.Add () is to be treated like an intrinsic: this means that the JIT knows exactly what it's supposed to do and doesn't need to actually compile the IL code in it. Ie, you catch early on the call to Datum.Add (), there is no need to do any advanced compiler optimizations. The current implementation here will be ignored once you have this implemented. using System; struct Datum { float f1; float f2; float f3; float f4; Datum (float val) { f1 = f2 = f3 = f4 = val; } void Add (ref Datum b) { f1 += b.f1; f2 += b.f2; f3 += b.f3; f4 += b.f4; } void Print () { Console.WriteLine ("{0}:{1}:{2}:{3}", f1, f2, f3, f4); } const int count = 100; static void Main () { Datum[] array = new Datum [count]; float f = 0.1f; for (int i = 0; i < count; ++i) { array [i] = new Datum (f); } for (int i = 1; i < count; ++i) { array [i].Add (ref array [i - 1]); } array [10].Print (); array [count - 1].Print (); } } Second Task: Pick one of two: * GC Analysis * JIT and Generic Analysis * GC Analysis. Given the description in: http://www.mono-project.com/Compacting_GC and the implementation in mono/metadata/sgen-gc.c describe briefly 3 changes to the GC code and/or JIT-GC interface that would provide a significant performance speedup. Explain the changes, the reasons it will improve performance and provide rough speedup numbers with a benchmark of your choice. * JIT and Generic Analysis Mono supports generics in its compiler and VM, this means that code like this is supported: class MyStack<T> { T [] storage; int top; MyStack () { storage = new T [10]; } public void Push (T datum) { storage [top++] = datum; } public bool Empty { get { return top == 0; } } } If the above code is used like this: MyStack<object> object_stack = new MyStack<object> () MyStack<string> string_stack = new MyStack<string> () MyStack<int> string_stack = new MyStack<int> () Explain: * When a generic class is instantiated, what pieces of code are shared? * Why they should be shared? * Are they shared in Mono? * If yes, why? If not, why not? * How could this be improved?