The Limber Lambda

Eric Smith’s technical musings

Archive for the ‘Development’ Category

Senior Developer Assessment: Re-aligning Expectations

with 20 comments

Today we assessed our 20th candidate for position of senior developer, using a small test that I drafted some time ago.  Since then I’ve spoken about how the test was dumbed down since one of the questions was perceived as being too difficult.  The assessment consists of three questions, which I’ve dubbed Fibonacci, Quicksort and University.  I’ve already discussed two of the questions, namely Quicksort and University.

Although not an earth-shattering sample, 20 is a number that we can start to draw pretty graphs with, so I’ve included a summary of the results alongside.

image

We can speculate about what it tells us:

  1. There’s something wrong with University; nobody has come up with a satisfactory answer;
  2. In the case of Fibonacci, there’s something wrong with the candidates; only five people have come up with a satisfactory answer.

Ok, my second conclusion above is possibly a little harsh.  I think it’s a little harsh, because upon inspection by others, it’s elicited use of some power words like “mathlete” and “math-wiz”.

Now Fibonacci is the only question that I haven’t posted for all to see, mostly because I thought it was too simplistic and therefore quite uninteresting.  Given these results though, I’ve been prompted to reword it completely.  I mean, if only math-wiz’s have what it takes to do it then I can’t make any assumptions about the background that a candidate may have in the arithmeticmaths department.

What follows is the version of Fibonacci as it was up until now:

image

I’ve taken great pains to remove anything that may constitute an implicit (read “unfair”) assumption about mathematical background and I’ve reworded the question to provide a lot more hand-holding for the candidate.  This should also help in offsetting the nervousness factor.

Here’s my updated version:

image

image

Written by Eric Smith

March 5, 2010 at 11:31 AM

Senior Developer Assessment Revisited

with 24 comments

This is really part two of the article I wrote “What is a Senior Developer?”.  I’ve received some shrill feedback on my choice of assessment problem:

  • Too math’y!
  • Standards too exacting!
  • A bit much to ask of your typical commercial developer.

So I’ve taken this all to heart and decided to revamp the Solver question.  Actually, I’ve decided to drop it completely and replace it with something a lot less “math’y” but possibly no more representative of real-world requirements.

A suggestion that was given me: “get them to sort stuff”.  Ok, so what would making someone jump through “sort algorithm” hoops prove?  After all, these days, sorting things amounts to a call to List<T>.Sort—I mean honestly, who ever needs to resort to first principles when sorting these days?  I’m willing to take a different tack—if I’m testing something slightly different, that is, not knowledge, but the ability to absorb and apply … well then that’s slightly different.  Besides … dealing with pointers is generally seen as unnecessary masochism, but some people still regard it as crucial background to being a good developer.

So this time, I’ve actually taken the time to capture the requirements in detail; this amounts to softening things up a little since the general consensus seems to be that the original assessment was too demanding (at least, the Solver question was).

image

Quicksort, above, doesn’t test ability to perform research independently, and offers a lot of hand-holding, but it is somewhat less daunting than Solver.  I can’t help thinking though that things are being dumbed-down a little too much.

The dumbing-down:

  • This is limited to System.String, but could easily be extended to be generic (bonus points if the candidate takes the initiative to do this!);
  • I haven’t specified any constraints in terms of efficiency issues (the naïve implementation is, of course, a horrible memory hog);
  • I don’t know if I could provide any more hand-holding than this, it’s practically paint-by-numbers.

I have been somewhat vague about one thing, namely choice of pivot.  I have arguably been a little tricky in this question because the example isn’t consistent in how the pivot is chosen.  The astute candidate will quickly realise that choice of pivot isn’t crucial.

Here’s my solution, coded up in approximately 20 minutes:


	public static class QuickSorter
	{
		public static IEnumerable<string> QuickSort(IEnumerable<string> jumbled)
		{
			if (jumbled.Count() < 2)
				return jumbled;
			else
			{
				return
					QuickSort(AllLessThan(jumbled.ElementAt(0), jumbled.Skip(1)))
					.Concat(jumbled.Take(1))
					.Concat(
					QuickSort(AllGreaterThan(jumbled.ElementAt(0), jumbled.Skip(1))));
			}
		}

		private static IEnumerable<string> AllLessThan(string value, IEnumerable<string> others)
		{
			return AllSatisfying(others, s => String.Compare(value, s) > 0);
		}

		private static IEnumerable<string> AllGreaterThan(string value, IEnumerable<string> others)
		{
			return AllSatisfying(others, s => String.Compare(value, s) <= 0);
		}

		private static IEnumerable<string> AllSatisfying(IEnumerable<string> others, Predicate<string> predicate)
		{
			return others.Where(s => predicate(s));
		}
	}

Things to notice about my implementation:

  • It’s pretty much declarative, thanks to Linq, of course;
  • It’s not very efficient … no in-place swapping; that’s what you get in twenty minutes.

I think that this provides a less jarring assessment experience for a would-be candidate than Solver, especially if our candidate isn’t a math-wiz.

Written by Eric Smith

February 20, 2010 at 11:57 AM

Exposing your Applications Guts using IronPython

with one comment

Application guts (or indeed anyone’s guts) isn’t typically on ones “list of things to see”.  Quite often though, when presented with some perplexing behaviour on live, you end up wishing that you’d added a key piece of logging code to get you to the point where you had just enough visibility to be able to solve the problem.

As it turns out, if you’re writing a .NET application, there isn’t a tremendous amount of difference between a Debug and a Release build.  That’s because, of course, the compiler isn’t spitting out real machine code, but rather MSIL, and if any kind of optimisation ever happens, it happens at JIT time.  At the end of the day, if you’re talking .NET, the difference between being able to debug your application boils down to the availability of some .pdb’s and an INI file … that’s it.

Never-the-less, you may not actually have a copy of Visual Studio or WinDbg with Son-of-Strike installed on the machine that you’re interested in poking around your badly behaving live application with.  That’s why you’d be particularly interested in employing the services of a worthy logging framework like Log4Net or the logging block from Entlib at the outset of your enterprise development stint.  Just increase your log level to “debug” and you’re a-for-away … right?

There are a couple of issues with this:

  • Typically, you need to restart your application or service to get the higher logging level into effect—maybe you have a situation where you don’t want to do that; you just want to view state?
  • What if, even on debug level, you’re not emitting the detail that you need?  At the end of the day, you’re at the mercy of the vigilance of the developer who wrote the debug entries—they may just not be enough.

How about bundling a little back-door into your app?  You could:

  • Get at it using something available on any PC, namely telnet;
  • Do anything that you would be able to do using code, only dynamically.

Enter PythonServer, available on github.  Let’s take it for a run using the (very) simple sample application:


static void Main()
{
	Console.WriteLine("Starting...");
	var theFibber = new Fibber();
	var pythonServer = new TheLimberLambda.Utils.PythonServer(2323,
		new [] { new NameBinding("fibber", theFibber) });
	pythonServer.Start();
	Console.ReadLine();
}

SimpleSample fires up a console, instantiates an instance of Fibber and starts an instance of PythonServer, listening on port 2323.

Fibber is just an implementation of IEnumerable<int> that spits out Fibonacci terms, but the key point is that it was instantiated in and lives inside the SimpleSample process.  We keep SimpleSample from exiting by waiting for input on the console.

Telnet’ing into localhost on port 2323 gives us an interactive Python command-line, so legal Python will execute as expected:

image

The real kicker here though is that we have access to our SimpleSample process, and anything that we decided to publish is available to us (in SimpleSample’s case, that would include our instance of Fibber).  Since Fibber implements IEnumerable, we can benefit from IronPython’s automatic recognition of anything IEnumerable as a Python iterator:

image

Here we’re using the itertools package that comes with Python (or in our case, IronPython) to grab the first 10 items of the Fibonacci series.

Because we’re referencing a single instance of Fibber, and because the state of “where we are” in the series is maintained, we can telnet in from a difference spot, and ask for the next two items:

image

Thus, we have a Python interface into potentially any .NET application.

Name Binding

Now, how did the name “fibber” become available to us, you may ask?  The key is the IEnumerable<NameBinding> that we passed to the PythonServer constructor.  At some point we need to provide some translation between the python namespace and the object instances of interest.  Presently, PythonServer does this using a dead simple string-to-reference map provided up-front.

Going under the bonnet and taking a squiz at the code that gets executed when a connection is made to the server, we notice the introduction of a ScriptScope instance:


		private void InitialiseScriptRuntime(Socket socket)
		{
			_ScriptRuntime.IO.SetOutput(new SocketConverserStream(socket), Encoding.ASCII);
			_ScriptRuntime.IO.SetErrorOutput(new SocketConverserStream(socket), Encoding.ASCII);
			_ScriptScope = _ScriptRuntime.CreateScope("py");
		}

… and binding names is just a matter of setting ScriptScope variables, thusly:


		private void BindScriptScopeNames(IEnumerable<NameBinding> nameBindings)
		{
			foreach (var binding in nameBindings)
				_ScriptScope.SetVariable(binding.Name, binding.Target);
		}

I will admit that PythonServer has a way to go, and could do with a whole bunch of things, including:

  • A solid security model.  At the moment PythonServer should really only be used in controlled environments since of course there is no authentication (or encryption) to speak of—SSH should fit nicely here;
  • Integration of the name binding interface into your favourite IoC container.

As a start though, this provides a great means of getting into your process in a relatively hassle-free way.

Written by Eric Smith

February 14, 2010 at 6:11 PM

On Exceptions

leave a comment »

A while ago, Justin Etheredge posted an article on best practices for when, when not, how and how not to program with exceptions in .NET.

For the most part, I agree with what he says in this article, but felt that I needed to blow my own horn on some of these issues since I get to see some fundamental misunderstandings (“misgrokkings”?) on the purpose of exceptions in code that is written by some of the guys here.

Part of me wants to start off with a tirade on the definition of the word exception, but I’ll spare you and skip that—suffice to say that exceptions really are that; they’re not supposed to be something we worry about or deal with during most of our programming—they’re … well … exceptional.  They’re supposed to be part of that whole managed thing that everyone keeps talking about.  Do you remember the good old days of C programming where everything returned an int to keep track of errors (even if that int being non-zero occurred only 1% of the time?).

In any case, a list of Smith’s rules around exceptions follow.

Rule 1: Relax, don’t Catch It

For the most part, really—carefully consider the reasons for catching exceptions.  The only times you should catch exceptions are:

  • When you need to do some kind of teardown or cleanup, regardless.  That’s why we have finally—so this isn’t really a reason for catching an exception after all;
  • when you need to align the exception with the context of what you were trying to do—a typical example of this is where an unexpected runtime exception such as NullReferenceException is thrown and you want to provide some more problem context, so wrap it in a more meaningful exception and throw;
  • When you absolutely have to recover gracefully from a condition that would normally terminate the application—be really careful here – continuing on in what will essentially be an errant state can lead to even more problems;
  • In order to log an error using a logging subsystem.  There should really only be one of these—just before the exception is about to fall through to the runtime.

Rule 2: Be Specific

When catching exceptions (and after some long, hard deliberation to reach this decision), try to be as specific as possible.  We’ll want to do:

catch (IOException ioException)
{
    // Stuff...
}

… and not:

catch
{
    // Stuff...
}

Rule 3: Don’t Throw Stuff Away

Ok, I couldn’t resist that small pun—by doing this sort of thing, we are throwing information away:

catch (NullReferenceException e)
{
    throw new InvalidOperationException(
        “The dooda can’t be used with a gidgimigadge: “ + e);
}

We would rather want to do:

catch (NullReferenceException e)
{
    throw new InvalidOperationException(
        “The dooda can’t be used with a gidgimigadge“, e);
}

The latter preserves all stack trace information, the former throws it away.

What you hide will bite you

Someone once said to me:

Ignore small problems, they’ll either go away or become big problems.

I’ve tried to keep this article positive, but I just have to have a word on this one … as someone pointed out, everybody loves code they can hate, and this is my personal sleeping blanket:

try
{
    // Stuff...
}
catch { }

This is known as exception burying.  image

In my earlier days as a developer, tinkering with various obscure scripting languages (the more arcane, the better), I bumped into Perl.  When they say that you can do something in more than one way with Perl, that’s a gross understatement—this is why I said my goodbyes to the language some time ago.  Apart from not being able to remember all of the syntax due to it’s sheer size, because the syntax is so ambiguous, you can end up writing stuff that is perfectly legal but doesn’t do what you want it to.  My initial self-high-five after writing my first Perl program and having it run without any errors quickly turned to dismay and frustration when it didn’t appear to work.  That’s because unless you “use strict” in Perl (or the ‘-w’ command-line switch), it just works … in particular, things like referencing variables that you’ve neither declared nor assigned to is just hunky-dory.

My point is: warnings and errors are good, not bad, they provide visibility into your program and give you hints about what may turn out to be problems later on.  They allow you to avoid days of trying to track a bug down because an errant condition is being buried.  Don’t bury exceptions.

A word on the appropriateness of exceptions being thrown

The .NET base class library provides a range of generic exceptions that can be used to report errors (including ArgumentException, InvalidOperationException, NotImplementedException, ArgumentOutOfRangeException and various others), and these should be used if at all possible.  The important thing though it to distinguish between exceptions that have been built to be thrown by your code, and ones that haven’t.

I can’t really think of valid situations where NullReferenceException and OutOfMemoryException should be thrown in your own code—these are things that you would catch (once again, that decision needs to be made carefully) but not throw.

Written by Eric Smith

July 15, 2009 at 6:17 AM

Posted in Development

To/Not to Design for Test

leave a comment »

Recently someone raised what appears to be a contentious issue, that is, is it acceptable to “design for test”.  Personally, initially a proponent of the “don’t-prop-your-code-up-for-the-sake-of-tests” department, I am becoming more inclined to agree with the author of said posting.  Being able to completely isolate an object for the purposes of testing is a beautiful thing, but sadly it sometimes requires a whole lot of P.T. in the form of dependency injection frameworks and the like–we’re currently feeling this pain on a big project we’re working on.

Written by Eric Smith

August 6, 2008 at 1:42 PM

Posted in Development, Methodology

Tagged with ,

One for the hidden gems department

with one comment

Code Margin

Microsoft does it again by including something really useful in their editor but neglecting to let anyone know about it.  For those of you who miss the 80-column (or n-column as the case may be) text width guide from the old Borland editors, just apply the following registry change for the same in VS 2005:

[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\Text Editor]
"Guides"="RGB(192,192,192) 80"

As can be seen, the colour of the guide can be specified, as well as the number of characters at which it should appear.  Digging a little deeper, doing the following will also work; rendering multiple guides:

[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\Text Editor]
"Guides"="RGB(192,192,192) 80 120"

Written by Eric Smith

July 29, 2008 at 2:42 PM