The Limber Lambda

Eric Smith’s technical musings

What is a Senior Developer?

with 20 comments

So, at work we’re in this recruitment cycle again.  This time it’s aggressive, and we’re really after the cream-of-the-cream.  Those hard-to-find coding ninjas who generally don’t ever need to approach a recruitment agent, because of course, the second someone sniffs that they’re on the market, they’re wooed with shares and options and Wii’s and iPads and rubdowns.  It’s a mad scramble.  Did I mention that I’ve never had to approach a recruitment agent? ;)

The best way to finger these types is through someone you know who’s really good, who knows someone they worked with at some point who blew their socks off.  Unfortunately the network method has failed us—sadly it looks like all talent has gone deep underground, or left the country.  I’m partial to the latter because quite frankly, the quality of the meat that our corporate designated agent is passing our way has been found wanting … repeatedly.

But before I get ahead of myself—let’s approach this methodically, like we should a new project.

Step 1: Clearly define what we require

Enter the Senior Developer.  As expected, this is all too subjective … a quick zoot over to SO confirms our fears and leaves us unsatisfied: it depends.  I wish it was as easy as “Spanish male developer” (si señor!).

Being the “main technical peanut” using our PM’s terminology, the responsibility of defining the standard falls on my shoulders.  I do subscribe to Joel Spolsky’s “smart and gets things done”, but the definition somehow falls short … it just isn’t complete.

Drawing from that deep unknowable über-developer essence that I supposedly have access to, I therefore decree:

Senior Developer Quality 1: Professionalism

Now we all know that you can’t distil what makes a senior developer into one simple thing, but this is one of those undeniably big differentiators.  Can you do a good job, consistently?  If yes, then proceed to next assessment gate.

Senior Developer Quality 2: Intelligence

Where I come from, there seems to be this unspoken rule: “one doesn’t explicitly talk about smarts”.  Because of course, smarts is one of those things that if you don’t have, no amount of experience is ever going to improve the situation.  Let’s square up to this, for crying out aloud—if you want to be a senior developer you absolutely must be smart.  Preferably, very smart.

Senior Developer Quality 3: Passion

Another big differentiator from the unwashed Mort-cast.  You gotta wanna learn, all the time, during meals, on the can, driving to work, driving from work, on the treadmill, aside the water cooler and anywhere else you care to mention.  Senior developers have technology in their veins, they live it and breathe it.  Excitement isn’t derived from the promise of a ticket to the Super 14 final, but rather the appearance of a postal collection note for that 200MB/s write-rate SSD from Newegg.

Senior Developer Quality 4: Humility

Getting to the point of truly grokking that no matter how good you think you are, there’s always someone else out there who’s better than you are is a watershed moment.  In all honesty though, no-one enjoys an arrogant git … it just isn’t conducive to greasing the cogs of the team dynamic.  The more numerous the alpha-geeks in a team, the more critical the quality of humility becomes.

Senior Developer Quality 5: Experience

There’s a bit of cross-over here with quality 1, so let’s say that in this case we’re particularly interested in the sort of experience that gives you that technical “gut feel”.  After a number of years, the neural pathways have been set up so that you can generally “smell” whether something sounds right or it doesn’t (when interacting with colleagues), and your hunch about where problems may lie tend to be more often right than wrong.

Step 2: Screen ‘em

When it comes to finding good people, and when you don’t have the luxury of a network-enabled direct route, it boils down to a numbers game.

Spolsky advocates the phone screen, but we’ve opted for a technical assessment.  Do we really want to waste our time sitting down to chat with someone if they don’t make the bar?  So to be sure, this is an effort to weed out those who think they represent our definition of Senior Developer, but who don’t.

A simple test should suffice.  I drafted one this morning, and I’m going to publish one of the questions (with sample answer).  Now you’ll notice that the problem posed isn’t very challenging (although some of my colleagues beg to differ), but you’d be surprised at how many people who sell themselves as senior developers who can’t do it.

image

My lazy side originally opted to go for one of those shrink-wrapped multiple choice online assessments ala Brainbench.  I’m not going to mention the brand of assessment that is our corporate standard because I have nothing good to say about it—typographical errors, and code that wouldn’t compile in almost every single question?  I wasn’t impressed either.  Suffice it to say, it’s not Brainbench.  Whatever the choice of assessor though, all of these tests suffer from the same problem; they tend to test stuff that we would naturally expect to Google these days.  I don’t rate that as being particularly useful at all.

Solver, above, may seem overly mathematical and unrepresentative of typical “throw-stuff-in-a-database-and-pull-it-out-again” business requirements, but what it does do is very quickly highlight the sort of person we don’t want.

  • Do we want someone who can’t understand the question because it contains “nasty unknowable symbols”?  Even if you didn’t do maths at university, surely you did algebra at school?  That’s all you need to know.
  • Do we want someone who can’t do research on the Internet?  Jeepers, I even provided the exact Wikipedia search.  The corresponding article, predictably, contains pseudo-code for various algorithms—would you honestly need more than that?
  • Do we want someone whose brain can’t be stretched to understanding an iterative algorithm to which they haven’t previously been introduced?
  • Do we want someone who doesn’t know enough to fire up the browser and at least try “+”root-finding” +C#” on Google?  (Yes, I do check the browser history afterwards :)

Of course I’m not expecting Newton’s method here, simple bisection will suffice.  Even if our prospective senior has never attended a calculus class, I would expect her to be able to fathom this one unassisted.

Here’s my bisection code, written up and tested in 20 minutes—too much time, I might add, for what I would consider a senior who lives and breathes code:

	class Program
	{
		static void Main(string[] args)
		{
			var lhs = (Func<double,double>) (x => x * x - 3);
			var rhs = (Func<double, double>)(x => x * Math.Log(x));
			var diff = (Func<double,double>) (x => rhs(x) - lhs(x));
			const double threshold = 1e-5;

			Func<double,double,double> findRoot = null;
			findRoot =
			((l, r) =>
			{
				if (Math.Abs(l-r) < threshold)
					return l;
				var mid = (r+l) / 2;
				return (Math.Sign(diff(l)) == Math.Sign(diff(mid))) ? findRoot(mid, r) : findRoot(l, mid);
			});

			Console.WriteLine(Math.Round(findRoot(1,50), 2));
			Console.ReadLine();
		}
	}

Now the big problem with bisection, of course, is local minima, but that is a non-issue because I even provide a graph illustrating that there aren’t any local minima.

It’s time to wrap this post up, and defer description of the how testing against qualities 1 to 5 should be done to another one.  Today we presented our first senior candidate with Solver, but you can probably guess what the outcome was when I tell you that he couldn’t nail Fibonacci which was to print out the first 30 terms of the sequence of the same name.  Sad, indeed.


Written by Eric Smith

February 9, 2010 at 8:45 PM

Posted in Uncategorized

20 Responses

Subscribe to comments with RSS.

  1. [...] What is a Senior Developer? – Eric Smith explains the characteristics of a Senior Developer. [...]

  2. [...] a comment » 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 [...]

  3. What if the exact root is 2.154999 ? With given threshold of 1e-5 you can stop at 2.15501. Or at 2.15498 . The result of rounding will be different.

    zuchodrig

    February 24, 2010 at 7:21 PM

  4. If the exact root was 2.154999, and using a threshold of 1e-5, then the choice of stops wouldn’t be 2.15501 or 2.15498, but rather something like 2.155001 or 2.154998. I guess what you’re saying is that one *may* get a different answer, depending on choice of threshold? This is actually a good point, and for that reason, rounding isn’t a great idea. Using a different threshold sure as heck wouldn’t be grounds for penalty though. I need to change the wording to something along the lines of: “calculate to an accuracy of 1e-2 …”. Thank you for the feedback.

    Eric Smith

    February 25, 2010 at 5:10 AM

  5. const PRECISION = 0.001;
    var x : real;
    begin
    x := PRECISION;
    while abs (x * ln(x) – (x*x – 3)) > PRECISION do
    x := x + PRECISION;
    ShowMessage(Format(‘%1.2f’,[x]));
    end;

    // it prints 2.16, dunno, is my code good enough?

    hk82

    February 26, 2010 at 12:10 PM

    • @hk You solved the problem, didn’t you? The main thing is, you understood the problem, and that’s a whole lot more than most people do. That reminds me; I need to request it be to at least 8 places :)

      Eric Smith

      February 26, 2010 at 12:39 PM

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

  7. Thanks for the article. I like your Five Qualities criteria which overlap with a lot of other useful advice I have seen on finding good people. I would say those qualities are desirable in any software developer and I agree that such folks are hard to find.

    I mention the following only because you make a point of taking issue with typographical errors (although this nit is not exactly a typo, per se).

    The word ‘threshold’ is one word, with one ‘h’ in it. It requires no CamelCasing.

    Rob Fulwell

    March 1, 2010 at 1:28 AM

  8. Hello Eric, I just couldn’t resist having a quick go at this, but this is going to sound daft.

    Instead of the bisection method, I opted to go for the Newton–Raphson method. Now since I’m short on time, I decided to bash it out in excel (yes I could write a program to do it, by the time my IDE loads up..) anyhow my excel routine always converges at 1.873 regardless of what initial guess value I put in. I must have done the derivate wrong!

    I make it:

    xn+1 = X0 – [x0*log(x0)-x0^2+3 / log(x0)-2x0+1]

    I feel embarrassed and like a school dunce, I’ve left my mathematics go rusty!

    Someone please correct

    Anhar

    March 10, 2010 at 8:49 PM

  9. Anhar – that’s because in Excel, “log” means “log to base 10″, but the problem above uses the natural logarithm (“ln” in Excel).

    Of course, Newtons method relies on one having the analytical derivative of the function to solve (but never fear, WolframAlpha to the rescue! :)

    Eric Smith

    March 11, 2010 at 5:51 PM

    • Many thanks Eric!

      That did the trick, the Newton–Raphson method solved it really fast. e.g when I put an initial guess of 6, it converges in 4 iterations. Naturally a better guess like 3 does it in 3 iterations.

      Your right about having the derivative, thankfully apart from my Log vs Ln mistake my derivate (calculated on the back of mail envelope) was correct :)

      Anhar

      March 11, 2010 at 9:32 PM

  10. Here’s my hideous c++ solution (I’m a php web developer by day, but thought it’d be fun to solve this with c++):

    @main.cpp contents:

    #include
    #include

    using namespace std;

    /**
    * Takes a double and returns and int that has been rounded to the given precision
    * eg. 115.165, 2 returns 11517
    *
    * @return int
    */
    int round( double number, int precision ){

    double returned = pow( 10.0, precision );
    returned *= number;

    if( (returned + 0.5) >= (int(returned) + 1) ){
    return int(returned + 1.0);
    }else{
    return int(returned);
    }

    }

    int main(){

    double x;
    double y;
    const double precision = 2;
    const double step = pow( 10.0, precision * -1 );

    for( x = 0.0; x < 1000; x += step ){

    y = x * log(x) – x*x + 3;

    if( round(y, precision) == 0 ){
    cout << x << " " << y << " Solved" << endl;
    }

    }

    return 1;

    }

    Compile in shell with g++:

    $ g++ -Wall -O3 -o Solver main.cpp
    $ time ./Solver
    2.16 -0.00216624 Solved

    real 0m0.012s
    user 0m0.010s
    sys 0m0.000s

    Criticisms and improvements are very welcomed. Anyone know of a good place for more little problems like this? Had been eying http://www.springer.com/computer/theoretical+computer+science/foundations+of+computations/book/978-0-387-30770-1 for some time, but haven't gotten around to buying it yet.

    Nice article, btw :-).

    Steve Sperandeo

    March 12, 2010 at 11:33 AM

  11. Hello Again, decided to implement into actual code:

    here is the RootFinder Class:

    public class RootFinder
    {
    private double _x0 = 100;

    public void CalculateRoot(double Px)
    {
    if (Math.Round(EvaluateSolution(Px), 4) == 0) {
    Console.WriteLine(string.Format(“Solution :{0}”, Px));
    return;
    }

    object _x0 = Px – ((Px * Math.Log(Px) – Math.Pow(Px, 2) + 3) / (Math.Log(Px) – 2 * Px + 1));
    Console.WriteLine(string.Format(“Xn+1 :{0}”, _x0));

    CalculateRoot(_x0);
    }

    private double EvaluateSolution(double Px)
    {
    //To do: Use Maths Parser to pass evalution function as a parameter
    return (Px * Math.Log(Px)) – (Px * Px) + 3;
    }
    }

    and inside a console:

    class SolverOutput
    {

    void Main()
    {
    string tmpStr;
    RootFinder fx = new RootFinder();

    Console.WriteLine(“Please enter an intial guess”);
    tmpStr = Console.ReadLine;

    if (IsNumeric(tmpStr.ToString)) {
    fx.CalculateRoot(Convert.ToDouble(tmpStr));
    }

    Console.ReadLine();
    }
    }

    test it out, only takes around a few iterations to solve.

    Anhar

    March 13, 2010 at 1:24 AM

  12. Might as well uselessly provide my Java solution:

    public double solveEquation() {
    // Initial Equation: x * log(x) = x * x - 3
    // Which is:
    // f(x) = -x ^ 2 + x * log (x) + 3
    // Derivative (for Newton's appproximation):
    // f'(x) = -2x + 1 + log(x)

    double initialGuess = 1.1;
    for (int i = 0; i < 10; i++) {
    logger.debug("Current guess: " + initialGuess);
    initialGuess = initialGuess -
    (-1 * initialGuess * initialGuess + initialGuess * java.lang.Math.log(initialGuess) + 3) /
    (-2 * initialGuess + 1 + java.lang.Math.log(initialGuess));
    }
    initialGuess = roundToDigit(initialGuess, 2);
    logger.debug("Returning: " + initialGuess);
    return initialGuess;
    }

    public double roundToDigit(double number, int digit) {
    double power = java.lang.Math.pow(10, digit);
    return java.lang.Math.round(number * power) / power;
    }

    Someone

    March 21, 2010 at 5:16 AM

  13. You don’t expect Newton’s method?

    When I was a freshman engineer at Cornell, our CS100 course required solving a problem just like this for homework.

    What do you call someone who can write a program to solve for the roots of some basic equations?

    (a) “Senior Developer
    (b) Freshman Engineer.

    SHEESH. I’m a GIRL and I could do that when I was frickin’ SEVENTEEN.

    cheryl

    April 28, 2010 at 8:07 PM

    • Knowing what I know now, pretty-much no-one who’s done the assessment so far would have managed to get this one. Only four out of around 40 candidates have managed to get the Quicksort question right.

      Eric Smith

      April 28, 2010 at 8:36 PM

    • There is a difference between knowing how to solve a problem and solving a problem.

      Sure I learnt about LASER theory and built radio’s when I was only seven BUT I thats only because I had learnt to do that.

      So the real question is not what you how to solve, its how you solve what you don’t know.

      Anhar

      April 28, 2010 at 8:43 PM

    • Continued..

      Another difference is ‘learnt’ vs ‘understanding’, I remember for one of my Engineering Degree examinations, I had a brain freeze and forgot all the important equations (Mathematical Modelling and Analysis of Mechanical Systems). Lucky for me I understood the topic enough to derive the equations from first principles.

      Further, to add being a ‘Girl’ is logically irrelevant!

      PS apologies about my grammar, English is only my third language. I only learnt to read/write English in two weeks.

      Anhar

      April 28, 2010 at 8:52 PM

  14. My first instinct would be to simply try for all relevant N whether the sign of the difference reverses between N*0.01-0.005 and (N+1)*0.01-0.005. This was prompted directly by the “rounding not truncating” comment, which tells me that correct rounding is of particular importance for this customer.

    I would avoid the standard floating-point based algorithms because they might yield a result whose uncertainty happened to straddle a x.xx5 boundary, which I’d need to correct and/or check for explicitly, complicating things beyond what a quick test of basic programming ability ought to require.

    If a linear search were deemed too inefficient, I’d probably escalate to integer bisection to find the right N in N*0.01-0.005.

    (No, actually my FIRST first instinct would be
    10 PRINT “2.16″
    given that the program takes no input anyway and I already know the correct output).

    Henning Makholm

    May 12, 2010 at 3:41 AM


Leave a Reply