Implementation versus Behaviour

Another bugbear I’ve come across lately: Please answer the following question without mentioning the terms “heap” or “stack”: –

What’s the difference between .NET reference and value types?

I’ve asked a number of people this question lately, and, without fail, all of them have answered that the former are allocated on the heap and the latter on the stack. That is indeed one difference, but it’s an implementation detail. It could change tomorrow and your code would still behave in the same way. As a developer of a .NET language, it has a much smaller impact on how you write code than the real answer.

So what’s the real difference between the two? It’s how they behave when passed between methods i.e. value types are copied whereas reference types refer to the same instance.

Most everyone I prompt knows this, but do not think to say it when asked the original question.

Psychic LINQ

A relatively short post on cargo cult programming, particularly related to LINQ.

LINQ is a fantastic technology. The idea of making a platform-agnostic query language is a fantastic idea. You can write the same query, in C#, over an in-memory list or a database and from the client point of view treat it in the same way. Isn’t it wonderful!

I’ve recently carried out a number of job interviews where candidates had to answer the following question:

If you wanted to find all Customers whose name was “Isaac”, why would you use a .Where() clause over a collection of T rather than using a foreach loop and manually construct the result set?

The results were varied. What I was looking for was a discussion of the benefits of declarative versus imperative code; what versus how etc.; composability of queries etc.

Strangely enough, the most common answer I got was "LINQ is faster than a foreach loop". Why? Either because LINQ somehow "optimises" code to make it faster, or because it "doesn’t need to loop through a collection – it just ‘does’ a where clause over the collection so that it instantly finds it". Almost as if C# is doing magic! In both cases the candidates could not justify their beliefs with evidence – it was just their feeling that that “must” be the case.

Now, lets talk about the reality. I would direct everyone to Jon Skeet’s fantastic EduLinq blog series to get an in-depth understanding of how LINQ over objects works, but always remember this simplification:

The only methods and properties that LINQ has for all its query methods are sourced from IEnumerator <T>

  • Boolean MoveNext();
  • T Current { get; }

    That’s it. Think about that. There is no magic involved. If you do a Where() clause over a collection, you will enumerate the entire source. There is no “pixie dust” that will give LINQ the answer quicker than a foreach loop and an if / then statement – and bear in mind, foreach loops are just syntactic sugar over IEnumerator, just like the using statement wraps IDisposable.

C# interviewing standards

    Before I start, this isn’t an “elitist” rant of mine! Now that that’s out of the way…

    One thing that often gets on my nerves when interviewing developers is when people rate themselves out of 5 for a particular technology. Generally people tend to rate themselves on the following scale: –

  • 3: I have used this technology a few times and know what it is.
  • 4: I have used it on at least one project before.
  • 5: I have been using it for a while and think that I know it to the fullest.

    There is no 1/5 or 2/5 of course. No-one ever gives themselves 1 for a technology on their CV (after all, why bother saying you’re crap at something). And the worst part is, all this rating does is show how much you know that you don’t know in the subject matter. Let’s take C# as an example. Someone might know the following: –

  • how to create and use generic collections, and understand the benefits from a usability point of view over ArrayList
  • how to use e.g. foreach loops and basic flow control
  • they might know how to use LINQ queries on a LINQ-to-SQL data context

However, they may not be aware of: –

  • how to create their own generic classes, or how generics work underneath
  • what is the yield keyword and how it can be of use
  • what is the difference between IEnumerable and IQueryable, or what an expression tree is

    That’s all fine. But as far as this person is aware, they’re a 5/5 C# developer because they aren’t even aware of what they are missing out on. Perhaps they give themselves a 4/5 “just in case” there’s a keyword that they might have missed Winking smile Whenever I interview people, I’d much rather someone give themselves a 2 or 3 out of 5 and be honest about it – or perhaps surprise us with what they know – rather than big themselves up and then fall at the first hurdle. All that does personally is fill me with suspicion – after all, if they’ve given themselves a 5/5 for something and been caught out so quickly, all the other aspects of their CV should be treated with the same suspicion.

    My personal advice would be that unless you can back it up, don’t do it. Smile

    For what it’s worth – and I don’t consider myself an expert in it – here’s the sort of things I would look for if someone rates themselves out of 5 in C# (note I have tried not to mention things like design patterns etc. etc., but rather just knowledge of the language itself, and I suppose its relationship with .NET as well): –

  • 1/5: Understanding of basic control flow; try/catch statements; methods and  overloading; difference between static and instance members; properties; levels of encapsulation; object scope.
  • 2/5: Able to explore and consume new simple APIs with little guidance. Consume and understand generic methods and classes; can create standard LINQ queries and consume IEnumerables / IQueryables. Good understanding of value and reference types, boxing and disposing of objects. Good understanding of object lifetime and the GC. Understands Reflection and its pros/cons.
  • 3/5: Deep understanding of generics. Good understanding of the components of C#3 e.g. Extension methods, lambdas, expression trees etc. Comfortable with usage of Action<T> and Func<T>. Understanding of multi-threaded processes.
  • 4/5: Good understanding of the role of the compiler in C# and its relationship with the .NET runtime. Good understanding of yield keyword. Understanding of closures. Knowledge of Task<T> and it’s relationship with threads. Understanding of dynamic, both in consumption and the underlying technology.
  • 5/5: Expert level in nearly all areas e.g. compiler behaviour, memory allocation, expression trees, GC behaviour etc. etc. Perhaps your name is Eric Lippert, Anders Hejlsberg or Mads Torgersen etc. etc.?

I guess even someone like those individuals that I mention don’t know “everything” and the language because C# and it’s relationship with .NET is now so vast, and so complex, that no-one could possibly know the intricacies of every component of the language.

Now, I bet that people could write some great systems with just a 2/5 or 3/5. I would also say that there is little relationship between someone writing fault tolerant, readable and maintainable code and their knowledge of the language. All it means is that you have more tools at your disposal when faced with a problem; the challenge is knowing when to use the right one for the job at hand.