Wednesday, July 2, 2008

Why you need to be able to write code on a whiteboard

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/why_you_need_to_be_able_to_write_code_on_a_whiteboard.htm]

During a software engineering interview, you need to be able to write code on a whiteboard. During too many interviews, at multiple companies, I've seen candidate after candidate struggle to write simple code on the whiteboard. Many of these candidates are decent people, with CS degrees, Master degrees , "years or experience", "senior developer" titles, etc... Yet they cannot write 10 lines of correct code on a whiteboard.

 

For example, such candidates will struggle to answer "given a array of integers, write a method that returns the sum of all the positive numbers." Seriously. This is just a few lines of trivial code - no advanced API, no design patterns, no trivia, no tricks. It's what you'd see in a college CS101, first semester exam:

public static int GetPositiveSum(int[] aInt)
{
  if (aInt == null)
    return 0;

  int intSum = 0;
  foreach (int i in aInt)
  {
    if (i > 0)
      intSum += i;
  }

  return intSum;
}

I've seen experienced, honest, candidates continually miss code of this simplicity.  They'll have logic, syntax, or style problems:

  • Logic - They'll add the numbers wrong, such as overwriting sum (intSum = i), or adding it exponentially (i += i), or completely ignore any validation (what if an input parameter of a public method is null?) It's one thing not to get bogged down in tedious plumbing, but a candidate should be prepared to call out if something could crash their code.

  • Syntax - A significant chunk of developers just dismiss syntax, emphasizing that they know the concepts instead. Good recruiters don't care about trivia, like if you miss a semi-colon at the end. But I've seen people have the wrong method signature, declare a variable wrong, have the wrong for-loop syntax, or reference an array wrong. A mistype is okay, but when you try to drill down on concepts ("Does the variable intSum need to first be assigned before being used?", "Will your loop execute the correct number of times?"), and they shrug it off, that's not good.

  • Style - Style is subjective, but important none-the-less. A good recruiter doesn't care if you indent with two spaces or four spaces. But there are other "style choices" that really do matter. I've seen developers declare their variable out of scope, such as using an extra static member instead of keeping it encapsulated as an instance field. I've also seen many devs just dismiss validation by wrapping the method in a try-catch. Or they'll make a method instance when it could be static instead. It's okay to have personal coding preferences, but these kind of "style" things actually affect the functionality of the code. A candidate should be prepared to explain why these made certain "style" choices.

Obviously, recruiters know that the candidate can write code, and could stumble through 10 lines of C#. But the idea is that if a candidate struggles to write trivial code, without the aid of Visual Studio's intellisense, compiler, and debugger, then they don't really get it. In other words, if a candidate uses VS as a crutch for simple code, then they're probably just "coding by coincidence" as opposed to proactively thinking through the code. And while you can "code by coincidence" for easy problems, on small, standard, applications, it will result in endless bugs on larger, complex apps. For example, if a candidate doesn't realize that they need to check for a null input parameter on simple code (even when prompted), how can they be expected to validate complex and critical code?

 

Some interviewees seem to dismiss these coding questions as "beneath them". The problem is that you must judge the unknown by the known. If a recruiter observes the candidate mess up simple code (that the recruiter can see), they'll be less likely impressed by fancy-sounding projects that they [the recruiter] cannot see. In other words, if for whatever reason the candidate cannot conceptually work through simple code, most recruiters won't even pay attention to all that allegedly complex code that the developer wrote elsewhere.

 

As a candidate, this coding on the whiteboard is the chance to shine. This is not the time to say things like "I guess this is how you do it", or "I'm trying to remember back in my college days". Rather, this is where the candidate can show that they know C# so well such that they can write it straight - without any crutch - and then explain it, and then adapt it on the fly. Now that's a great way to get off to a good start in an interview.

 

 

FYI, here are some of the unit tests that I'd run the above code through:

Assert.AreEqual(0, GetPositiveSum(null));

Assert.AreEqual(0, GetPositiveSum(new int[] { 0 }));
Assert.AreEqual(0, GetPositiveSum(new int[] { -1, -4, -4 }));
Assert.AreEqual(0, GetPositiveSum(new int[] { 0, -4 }));
Assert.AreEqual(0, GetPositiveSum(new int[] { Int32.MinValue }));

Assert.AreEqual(4, GetPositiveSum(new int[] { 4 }));
Assert.AreEqual(10, GetPositiveSum(new int[] { 1,2,3,4 }));
Assert.AreEqual(4, GetPositiveSum(new int[] { -4, 4 }));
Assert.AreEqual(Int32.MaxValue, GetPositiveSum(new int[] { Int32.MaxValue }));
Assert.AreEqual(3, GetPositiveSum(new int[] { 0, 1, 2, -3 }));

.

 

Tuesday, July 1, 2008

Why you shouldn't just wrap simple code in a try-catch

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/why_you_shouldnt_just_wrap_simple_code_in_a_trycatch.htm]

Structured programming languages, like C#, provide a try-catch ability to wrap an entire block of code, and catch if anything goes wrong. This can massively simplify error checking, especially when calling external components. However, like any good thing, it can also be abused. During interviews, or rushing out code, many developers resort to using try-catch as a quick way of doing error checking, but there's a catch (excuse the pun). For example, consider this trivial method to sum up an array of integers:

 

    public static int GetSum(int[] aInt)
    {
      int intSum = 0;
      foreach (int i in aInt)
      {
          intSum += i;
      }
      return intSum;
    }

 

You can crash this code, such as by passing in null for the int array.  To blindly wrap a simple method with try catch, just to catch normal logic errors like null variables or indexOutOfRange, has problems.

  • For performance, Try-catch is enormously expensive compared to an if-then check. It could be hundreds of times slower. So it's bad design to use a try-catch for something trivial when an in-then will do just file, like checking if a variable is null.

  • What will you do in the catch statement? Some devs may say "I'll log my exception info here" - but what info is that... that the developer didn't bother to do basic error checking?

  • It makes the usability worse. Perhaps instead of re-throwing an exception, or logging and going to the global error page, the method could have used an if-then to return a sentinel value instead. For example, perhaps a string manipulation method could just return the original value (or null) if the input parameters were invalid.

  • It loses context. Say your code catches a null exception - that thrown exception doesn't tell you what variable was null. You've lost context and information with which to fix the code. Using an in-then would have given you full access to all the local variables and their context.

  • It makes all exceptions equal - a null or indexOutOfRange exception (things that are easy to catch with if-thens) are put on the same level as a critical outOfMemory error - i.e. both trigger the catch block. This in turn can distract the maintenance team, who gets swamped with tons of exceptions, most of them preventable.

  • Perhaps worst of all, it implies that the developer isn't thinking about how their method can fail. Rather than understanding the code and what it does, they just wrap it all in a try-catch, and move on. This means they could have not coded for valid use cases.

Try-catch has obvious benefits, but it has limitations and consequences too. There are times when it's much more beneficial to explicitly catch the error conditions with an if-then instead.

Monday, June 30, 2008

The problem with "I'll wait until my manager sends me to training"

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/the_problem_with_ill_wait_until_my_manager_sends_me_to_tra.htm]

With all the new technologies coming out, many software developers want to get sent to training seminars. Sometimes "Training" is fun - your company spends thousands of dollars to send you to a fancy building, during regular working hours, where you have an in-person expert guide you through some marketable skill. It lets you feel like you're part of an elite group, and on the insider track. Usually these sessions even provide free snacks!

This is great - until a developer uses it as an excuse for inaction, as in "Rather than learn technology XYZ on my own, I'll wait until my manager sends me to training." For the vast majority of mainstream development technologies and techniques (C#, SQL, JS, HTML, XML, security, performance, automation, etc...), such thinking has some big problems.

  • Because live training seminars are expensive, managers are very reluctant to send you.

  • If you're truly motivated, usually there are free (or cheap) alternatives instead. For example, there may be free user groups that meet in your area that offer presentations on hot topics. Sometimes there are even free MSDN events. Worst case, you can buy the $50 book.

  • Therefore, by the time management is willing to sink $3000 to send you to a training seminar, you could probably learn it faster yourself via some other method.

Having special training for a cutting edge technology or proprietary tool is great. But a motivated developer shouldn't need to wait to be sent to training before learning C#, or how to improve code performance because that information is already freely available in many other formats besides in-person training seminars.

 

Sunday, June 29, 2008

Silverlight TruckWars 2.0 - Migrated to SL2 Beta 2

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/silverlight_truckwars_20___migrated_to_sl2__beta_2.htm]

I migrated Silverlight TruckWars to the SL Beta 2. I started working on TruckWars as a way to learn Silverlight back in the Alpha last year. Being a Microsoft product, there have been two more betas (with plenty of breaking changes), but I've finally migrated it.

 

Things of note - Beta 1 started supporting buttons, which obviously simplified things. For example, it helped me remove keyboard input. It also had some subtle changes that affected the gameplay. Also, there still is no dropdown. Before I was using an HTML dropdown to select the levels. Rather than jump through hoops, I just ceded the dropdown part until the next release.

 

Because the code has been migrated from an alpha, to a beta, to another beta, it's becoming pretty screwy. Not the best, most agile code out there, but good for a demo of what cool stuff Silverlight can do. You can play it here.

 

Friday, June 27, 2008

The first LCNUG meeting - Windows Workflow Foundation

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/the_first_lcnug_meeting__windows_workflow_foundation.htm]

The first LCNUG meeting occurred this past Thur, June 26. It went well - about a dozen (very talented) people. Scott Seely presented on Windows Workflow Foundation, which you can download from the website. The small number of attendees (as compared to the hundred who normally attend larger groups) allowed more community interaction and networking. Overall, a good success for the kickoff meeting of a new group. I'm proud that Paylocity can help sponsor this.

 

Tuesday, June 24, 2008

Do you have time to blog?

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/do_you_have_time_to_blog.htm]

I enjoy blogging, so I encourage others to try and enjoy it too. I've met many people who say they'd like to blog, but "just don't have the time." I understand that we're all busy. I figure a single blog post can be small, with a few paragraphs, much like a big email. And, an average blog may have 2-3 posts a week. So, if you can cut out just one pointless email, every other day, then you'll have enough time to blog. And if you blog about what you're actively working on, then it's much faster, because the words, concepts, and code snippets are already at the tip of your tongue. Optimistically, there are ways to squeeze blogging into one's life.

Monday, June 23, 2008

Minimalist Code Samples

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/minimalist_code_samples.htm]

A minimalist code sample is a snippet that demonstrates a specific purpose, requires no extra context, yet can still run. For example, doFactory.com explains design patterns with a "real-world" sample, and a "structural" (i.e. minimalist) sample. Because it abstracts out the context, the minimalist sample has several benefits:

  • Easier to apply: It is easier to apply to different contexts - such as new projects.

  • Easier to remember: It is much smaller (no context means less code), therefore it's easier to remember what the code was about. For example, I have a folder essentially called "LearningSnippets", where I categorize different coding tricks. By keeping all the snippets small, they're fast for me to physically load, "mentally load", and then run. The last thing I want is to dig through some 2000 line project, scratching my head, thinking "how did I do that sorting algorithm?"

  • Easier to learn: It's easier to learn new concepts. Removing the irrelevant context means there's less to get distracted by, so you can focus on the specific concept that you care about.

  • Easier to show others: It is easier to show to others, such as a newsgroup, where other developers don't care about the business context. I sigh when I see some poor guy post a 5 page code question on a forum, because few people will sift through all that.

  • Easier to enhance: It can be much easier to enhance because the code is not constrained by some rigid business context.

  • It is a courtesy to others: If you just care about a 3-line algorithm, it would be long-winded of me to hide that behind hundred of lines of business context and plumbing.

In .Net, many errors come down to a few bad lines of code - you've got the wrong method, a bad input parameter, or some syntax error. It becomes very convenient when working with others, or learning new concepts, to be able to isolate code down to the minimalist sample.