The Limber Lambda

Eric Smith’s technical musings

Slosh

leave a comment »

… is not a word that you’ve likely encountered too often.  It happens to be an alias for the ubiquitous backslash.

\

Now as a programmer, I’ve come to react to certain ASCII characters instinctively:

#

“Smells like a comment”

/

“Looks like a path component delimiter”

.

“Wants to be in a namespace”

\

“Careful … things aren’t as they seem”

That last one is special … it transcends ordinary meaning.  That’s because its scope extends beyond just itself … to what follows it.  And that, with little argument, is generally accepted the world-over.  The backslash character is the universal escape character.  Why then, is it so difficult for Microsoft to get in line?

Larry Osterman sums up the origins of the gross misuse of the backslash character:

Many of the DOS utilities (except for command.com) were written by IBM, and they used the "/" character as the "switch" character for their utilities (the "switch" character is the character that’s used to distinguish command line switches – on *nix, it’s the "-" character, on most DEC operating systems (including VMS, the DECSystem-20 and DECSystem-10), it’s the "/" character" (note: I’m grey on whether the "/" character came from IBM or from Microsoft – several of the original MS-DOS developers were old-hand DEC-20 developers, so it’s possible that they carried it forward from their DEC background).

The fact that the "/" character conflicted with the path character of another relatively popular operating system wasn’t particularly relevant to the original developers – after all, DOS didn’t support directories, just files in a single root directory.

Then along came DOS 2.0.  DOS 2.0 was tied to the PC/XT, whose major feature was a 10M hard disk.  IBM asked the Microsoft to add support for hard disks, and the MS-DOS developers took this as an opportunity to add support for modern file APIs – they added a whole series of handle based APIs to the system (DOS 1.0 relied on an application controlled structure called an FCB).  They also had to add support for hierarchical paths.

Now historically there have been a number of different mechanisms for providing hierarchical paths.  The DecSystem-20, for example represented directories as: "<volume>:"<"<Directory>[.<Subdirectory>">"FileName.Extension[,Version]" ("PS:<SYSTEM>MONITR.EXE,4").   VMS used a similar naming scheme, but instead of < and > characters it used [ and ] (and VMS used ";" to differentiate between versions of files).  *nix defines hierarchical paths with a simple hierarchy rooted at "/" – in *nix’s naming hierarchy, there’s no way of differentiating between files and directories, etc (this isn’t bad, btw, it just is).

For MS-DOS 2.0, the designers of DOS chose a hybrid version – they already had support for drive letters from DOS 1.0, so they needed to continue using that.  And they chose to use the *nix style method of specifying a hierarchy – instead of calling the directory out in the filename (like VMS and the DEC-20), they simply made the directory and filename indistinguishable parts of the path.

But there was a problem.  They couldn’t use the *nix form of path separator of "/", because the "/" was being used for the switch character.

So what were they to do?  They could have used the "." character like the DEC machines, but the "." character was being used to differentiate between file and extension.  So they chose the next best thing – the "\" character, which was visually similar to the "/" character.

And that’s how the "\" character was chosen.

Everywhere else we instinctively know that a backslash escapes things … everywhere … except for Windows/DOS path names.

In defence of Windows, the OS is perfectly happy to interpret slash (“/”) as it would slosh … and for the most part application software observes this.  There are occasional heretical instances where this is not true though and the application software writer has (<<shudder>>), deliberately chosen the backslash as a categorisation delimiter.

So, today I battled through an instance of this, trying to call sqlcmd.exe from within a Bash script.  Now I realise that this is largely a function of the implementation (which was re-expanding parameters multiple times before they were eventually passed to sqlcmd.exe), but oh how this would so have been a non-issue if someone, somewhere had simply respected the good ‘ol escape character and left it to only ever escape and nothing more.

What was needed in the invocation of my Bash script:

image

… to eventually get into the form that sqlcmd.exe desires:

image

What a wonderful place the world would be if we could all agree on one thing: slosh is for escaping … nothing more, nothing less.

Written by Eric Smith

May 28, 2010 at 6:12 AM

Posted in Opinion

The Skill to Learn

with one comment

I’ve been working now for some fifteen years, and I think that for someone who’s had a bit of experience, they can honestly look back and draw some valuable conclusions on “what’s important”.  By implication, there are also a whole bunch of things that are not important.

Today, sitting with a prospective hire, I was asked what I thought of courses.  I interpreted it is a question about the value of courses, in general.  That’s a tough one.  Any academic endeavour, ultimately, is only worth it’s level of recognition, presumably by a body or group of bodies whose opinion one values.  The only truly worthwhile “course”, in my opinion, is one that you get through a reputable university.  Ultimately, it then boils down to what is meant by “reputable”.

In IT, there will always be a market for courses.  At first this statement seems obvious—after all, isn’t the way one learns how to administer an instance of Microsoft Exchange, or SharePoint, or Microsoft CRM is through a course?  Is this the only way?  If you’re a corporate charged with maintaining a level of skill within the org, it sure seems like the only way … it sure is the most expedient (at least at first glance).

The course-peddlers know this, and they exploit it.  Corporates are easily wooed by the promise of the training silver bullet.  It’s money for jam … time away from the office and the shelling out of a few shekels brings you back shiny new Exchange-ready employees the following week.  There’s a problem with this though, it’s subtle—they’re Exchange-ready … yes, but they’re not really Anything-Ready, and that’s what we should really be looking for.

Anything-Ready

Anything-Ready is a meta-concept … it’s not about anything particular that you may know, or that you may need to know, but rather how good you are getting to know what you need to know.  I’m not looking for Master Exchange Certified, or SCRUM Master Certified … I’m looking for Master UPSKILL Certified, All-Technologies-Applicable.  Now that is valuable.

Which brings me back to why I place value in a university degree.  When you go to university, you learn how to learn, and if you’re lucky enough to go on to do a post-graduate qualification, you get first exposure to Anything-Ready 101.  I’m probably being unfair in that this judgement really has been made through the lens of technical degree … can’t vouch for a BA.  Ultimately though, there’s still a whole lot of learning to do before you graduate as “Anything-Ready” and that’s the job of industry.  True Anything-Ready graduates are the product of years of industry-grind-mill, post university degree.

So .. what is Anything-Ready?

Anything-Ready

Apart from getting your daily dose of mental calisthenics, addressing the root cause means that you’re eliminating a fear—that’s because if you haven’t gotten to the nub, you will always remain in fear of what may pop up later on because you chose to shortcut grokking the problem.

You can spot a course-taker a mile away, she tends to shy away from anything not within the ambit of what has been explicitly learned—face your fear and become a polyglot.

A keen study of Anything-Ready knows that the “Ready” part needs constant attention—regular reading is a must to maintain that status.

I continue to be astounded by the number of programmers who haven’t mastered the bread-and-butter of their tools.  If I had a penny for every “senior programmer” I’ve met who can’t touch-type… Jeff Atwood says it far better than I could.  As for your editor … choose one, embrace it, get to grok it, because if you’re a programmer, it’s the canvas of your craft.

No man is an island.  Programming and Autism—two peas in a pod?   It doesn’t have to be that way.  Humans are computers … just really complex ones, and it does take a while, but every programmer eventually figures out that solving certain problems can be done an order of magnitude faster through a small human interaction than solitary toil.  So keep community, not so much for the selfishness of getting what you need quickly, but for the benefit of your own soul.

There’s no barrier to entry with programming.  Anyone with a laptop and an Internet connection can do it.  More alarming though—anyone with a laptop and an Internet connection can convince Joe Sales Exec that they can do it well.  That’s why the keeper of “Anything-Ready” faith knows how important always beats urgent.  The “sins of the fathers” is a biblical meme that applies everywhere, not least in programming—careful what decisions you make, because they form more of a legacy for those who come after you than you may think.

It’s incumbent on us to be vigilant about what’s important.  If we don’t, we’re in danger of wasting time.  Distilling what’s important is about cutting to the chase and removing waste.  It’s another way of repeating DRY (the only time you get to repeat yourself and feel good about it).  Anything-Ready-practitioners are voracious distillers of what’s important.

Someone who is Anything-Ready knows that it’s tenuous title.  They don’t call it the fire hose for nothing.  Do you know someone who can actually drink from a fire hose? (no spilling).  So keep that ego in check—there’s always someone around the corner way smarter than you.  Really.

Back to Courses

Courses aren’t all bad.  A good course will:

  • Provide a formal, structured means to refocus;
  • Expose you to people who you wouldn’t normally have had the chance to meet;
  • Put your bosses mind at ease that the “skill issue” is being addressed (definitely a soft benefit);
  • Keep the paper mills afloat.

Written by Eric Smith

May 25, 2010 at 6:26 AM

Posted in Opinion, Recruitment

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

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.

Written by Eric Smith

February 27, 2010 at 5:01 PM

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

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

Doing a Good Job

with 2 comments

I’m going to say something shocking …

Your degree that you worked for for years doesn’t mean a whole lot.

I can say that, because I was living proof.  I studied for six years and ended up with a masters in electrical engineering.  At the end of it all though, there’s only one pertinent question:

Can you do a good job, consistently?

And, I’m ashamed to say that at that time, as a fresh start in my first job, I could not reply “yes” to that question, at least according to my present-day definition.

So, what does “good” mean? you may ask.  Good point.

It can be argued that it’s in the eye of the beholder, but “good” can be characterised by a range of things and it’s pretty much universally recognisable:

  • It’s complete.  The proverbial i’s have been dotted, and t’s crossed.  It’s been checked, and cross-checked.  Complete has an “aroma” to it—you actually want someone to look at it—you’re proud of it.
  • It’s timely.  Part of “good” is sticking to your word—you said it would be finished by the end of the week?  Make it so, by hook … or by crook.
  • It’s succinct.  There’s been an effort to ruthlessly focus on what’s important.  Just because the annual budget is important, it doesn’t have to be voluminous.
  • It’s correct.  That means you’ve proof-read it, and possibly even got someone else to proof read it.  If it’s code you’re writing, you’ve written automated tests to confirm that it behaves the way it’s intended to.
  • It has built-in continuity.  Someone needs to extend it or enhance it?  No problem, there’s a Readme that bootstraps you … and the code is “literal” (not necessarily Knuth’s definition, but aspiring to be).  The way to nail this one is to regularly put yourself in the next persons shoes.
  • It’s transparent.  It’s built to be absorbed by other human beings—there are no gotcha’s.  If it’s code, it isn’t too “clever”.
  • It fails fast.  When you build something, you need to be in the place where you know it’s going to fail.  Good is not perfect.  So when it fails, even when the condition seems innocuous, fail fast and fail hard.  That’s because too much energy is expended on hiding and fretting than failing and fixing.

The thing to notice about all the points above is that they’re not actually taught at school, not explicitly at least.  For me, that’s ironic—because knowing what I know now, I would take someone who’s got those things down pat any day over someone who has a PhD but who can’t deliver.

So, it’s worth ruminating on today: “Am I doing a good job?”.

Written by Eric Smith

December 2, 2009 at 5:38 AM

Posted in Opinion

Mort Revisited

leave a comment »

Today I attended an interview for a prospective VB6 candidate.  Are there serious developers out there who actually want to develop in VB6 going forward, without a prospect of perhaps moving onto a newer platform?  Apparently there are.

Asks I: Can you tell me what polymorphism is?

Says prospect: [paraphrased] It’s when you have a method that takes two parameters, say x and y and another method with the same name that takes three parameters, x, y and z.

Asks I: Say for instance you have an array of strings … a bunch of names of people … but they’re all jumbled up, how would you get them into alphabetical order?

Says prospect: I would do an “order by”.

Asks I: Can you tell me what COM is all about?

Says prospect: It has to do with objects and DLL’s (waves hands in air for effect).

Asks I: Can you tell me what a hash table is?

Says prospect: No [pause] … [a "go-on-give-it-a-go" nod from me]

Says ex-prospect: Aren’t you going to tell me?

Evidently Mort and his cohorts are alive and well and being paid real shekels for propping up those critical business systems.  Afterwards a colleague called me out for asking irrelevant questions like … well, who in the world is expected to know what polymorphism is?  Especially in the VB world (puh!).

This just re-affirms my (reluctant) assertion that it doesn’t really take rocket scientists to keep critical business systems running.  It doesn’t even take people who are mildly interested in furthering their career of choice.  When the proverbial hits the fan, folks may end up running around screaming blue murder for a while, but the problem will be fixed, and more than likely it’ll be fixed with a little duct tape.  Until of course the tape peels off, and a patch over a patch is required.

Let’s say that again–the system will be fixed.  It might be expensive, it might be inelegant, it might take a couple of days off someones life, but things will carry on, and in a year or two the cross will be borne by a new eager victim, one who may even have been lucky enough to have had a mere brush with a computer science text book (we can only hope).

Sadly I have no wise rebuttal right now, because the numbers just aren’t there.  And that is, simply put, why some people can play pied piper to the development masses and lead them into dubious territory.  Our industry is a young one, too young still for the toll of poor practice to be quantified.  My most effective contribution right now then is to continue playing disciple to the way of Uncle Bob and hope that one day, all will be converted.

Written by Eric Smith

November 3, 2009 at 5:00 PM

Posted in Opinion

PubSubHubbub Hullabaloo

with 2 comments

Anil Dash recently wrote an article on what he calls the Pushbutton Web, a catch-all term not dissimilar to AJAX that describes the popular concept of technology initiatives related to the real-time web.  The assertion is that open protocols like PubSubHubbub are the future means by which we’ll get real-time updates, that is, the real-time web will no longer be the exclusive domain of semi-proprietary protocols like those used with Twitter and Friendfeed.

PubSubHubbub sets out a way for subscribers to be directly notified when there’s an update to a providers RSS or Atom feed.  Here’s how it works:

pshb

  • Firstly, the content provider (Any RSS source such as FeedBurner) requests a selected hub to respond to future notification pings about updated content (1);
  • When a subscriber (choose your RSS reader) asks for content (2), the response (3) contains not only the newest articles but also some metadata informing the client that there is one or more hub that can be used for notifications;
  • Subscribers subscribe to content updates by asking the designated hub for updates (4);
  • As updates come in (5), they’re broadcast to interested subscribers (6).

Something key that I haven’t mentioned about the diagram above is that the lines represent HTTP requests and responses (blue are requests, green are responses).  The dotted lines represent the “push” part of the protocol.  Something that’s noticeable to anyone who’s ever had to do any networking or administration of a firewall is a rather naive assumption about the connectivity between the hub and the Subscriber.  Now, if by “Subscriber” we’re talking about your typical Internet-connected workstation, then there’s something missing in this picture.  That’s because the vast majority of Internet connected workstations connect via a firewall or a NAT device.

In practice, this translates to:

 pshb2

And trying to hunt down a response by the designers to this little snag reveals:

"I’m behind a NAT. Can I subscribe to a Hub? The hub can’t connect to me."
Anonymous
 

No, PSHB is a server-to-server protocol. If you’re behind NAT, you’re not really a server. While we’ve kicked around ideas for optional PSHB extensions to do hanging gets ("long polling") and/or messagebox polling for such clients, it’s not in the core spec. The core spec is server-to-server only.
Brad Fitzpatrick, San Francisco, CA
 

Looks like the final word on the matter. PSHB is not intended to be used by Internet connected workstation subscribers.  How then does PSHB help us get closer to an open-standard Twitter or Friendfeed?  In the short term, at least, it doesn’t.

So, to conclude, for all practical purposes, our “real-time-web” world is going to be one of piggy-backing the HTTP response, in it’s various incarnations.  To the purist, this spells “hack” and PSHB clearly hasn’t compromised on this one.  Hopefully firewall vendors out there will build in the ability to respect and forward incoming PSHB notifications at some point.  Until then though, the Internet will use what’s simple, available and works—that one I will agree with Anil on.

Written by Eric Smith

August 10, 2009 at 8:01 AM

Posted in Opinion