Problem? No problem.

Painful revelation #5473984 since beginning to code: I need better problem-solving habits.  Sure, I’m plenty smart and can use problem solving skills if I really need to, but step-by-step problem-solving is not yet second-nature.

I didn’t realize how sloppy my problem-solving process was until I started school last year.  At that point, I had been doing JS on my own for about 9 months, and my approach to problem solving was as follows:

  1. puzzled stick figureSee a problem
  2. Brainstorm about what could be causing the problem -> {usually no idea}
  3. Fiddle with a few things and look for typos -> {typically creates even more problems}
  4. Get super frustrated
  5. Print out my entire database
  6. Anger-eat a sleeve of Oreos, taking no pleasure in them
  7. Undo everything back to just the one problem
  8. Binge-watch Parks and Rec until I can calm down enough to think about the problem again

Now, having looked on with some brilliant colleagues, I see that there are much less maddening ways to find bugs.  Even though many problems still start out as a ‘black box’ in my mind, I now take a much more scientific approach — something like this:

  1. See a problem.
  2. Distill the problem.  Say what you expect vs. what you are getting, or draw it on paper if it is complicated.  This helps you crystallize the problem in your mind, and sometimes even helps you solve it at this step.
  3. Isolate the problem function(s). This may mean commenting out sections of HTML or JavaScript in order to focus on just one part of the code.
  4. Simplify inputs and outputs.  Sometimes cluttered code or complex variable names can make a problem seem overly complicated.  Separate long conditionals into into multiple lines when you can; replace variable names with simpler names.  (Classic blunder: Just because a function is named “postToApi” doesn’t mean that calling this function will actually post to an API.  Sometimes semantic naming can trip you up by creating an assumption of functionality.)  If your program isn’t logging the object you expected, replace the object with a string like ‘foo’ make sure your log statement is being executed.
  5. Break the problematic part into smaller pieces and run through them one by one.  Split a complicated function into smaller pieces.  You can run each piece individually, then start putting pieces together one by one.  As you add each piece in, you’ll be able to see which addition breaks the combination. (Keep in mind — it may be more than one problem and likely is if you’ve gotten this far…)
  6. Watch EVERYTHING.  Watch each variable in the buggy snippet of code from start to finish using logs or a debugger statement.  See where the variables diverge from what you expected.  The nice thing about debuggers is that they often uncover contributing factors that you might not have suspected.

If all else fails, rewrite from scratch.  Sometimes you hit a point where you’re not making progress by debugging.  This can be caused by a stupid mistake, like a typo that you don’t see, or by a bigger logical flaw.  In either case, sometimes the quickest way to a solution is to re-write one or many parts of your function from scratch, without looking at the original.  This might sound like a cop-out, but you don’t always have time to walk away from a problem 10 times and come back to it; sometimes you just need a clean slate to rethink your approach.

Keep breathing.  Keep eating and drinking.  Go watch Ron Swanson eat a Meat Tornado, or whatever gets your mind in a different space.  An exhausted and frazzled engineer is like a bull in a china shop, perpetuating code problems through little mistakes and oversights, but a happy and healthy engineer is better than the best debugger there is.


An Arrival

Like any good engineer, I play archaeologist more often than architect.  Each day with tools in hand, I exhume the inner workings of someone else’s code and lay out the pieces, examining each tiny cog in turn.  When it is intact again, I learn forward to watch the values during the intangible thousandths of a second between functions.  Before me, the mechanism spins and whirs, only a tiny, occasional slip to denote any error.

Sitting at my console, I have my tools lined up neatly: sources, resources, linters, debuggers, timetables.  My job is to wait, watch the past unwind into the present until I can trace the fall of Rome back to that first hairline crack.

Today I succeeded, penetrating the thick, undulating layers of functions to pinpoint an error deep within our code base.  A couple of screenshots, a couple of tentative test-fixes later, I had sounded its depths and sketched out the solution, ready to tackle tomorrow.

I have found and fixed many errors before, but somehow this one was different.  I knew what I was doing, what I was looking for.  I navigated my way through almost seamlessly, without giving pause to those hiccups that were merely symptoms and not the root cause.


Drawing by Randall Munroe.

Today was an arrival. In the span of an hour, I brushed against that invisible curtain that separates proficiency from fluency.  I am filled with both an unshakable desire to return, and a certainty that I will.

How many Jr Engineers does it take to change a lightbulb?

It’s been said that a senior engineer is worth 10 junior engineers, and some days that idea haunts me.

Three months into my first engineering job, it’s tempting to feel no-good when I get stuck on another jasmine test, or screw something up in my git branch yet again.  My more experienced colleagues are faster and better at coding than I am, able to get to the root of a problem in seconds while I’m still desperately console-logging everything in sight.

But lately, I’ve been thinking about things in my job that I’m good at.  Even as the most junior person in the office, and partly because I’m the most junior person, some areas come naturally to me.  Here are a few examples of the things I’ve excelled at so far:

Being an intelligent test user. This is the one skill I’m most proud of.  As a detail-oriented person, I can sniff out a bug like a hound on the trail of a ferret.  As a detail-oriented person, I see technology from the Screen Shot 2014-03-06 at 9.13.36 PMtarget user’s perspective and easily find areas where s/he might get tripped up.  Over the last three months, I’ve made hundreds of github issues for features and refactors to make our app easier to use.

One recent example: Our ‘dirty’ input text color — dark orange — is so close to red that I kept thinking that my input values were invalid.  Like me, our users won’t realize that the dark orange is for a ‘dirty’ input (with dark orange color mimicking our logo); they will just wonder what they’ve done wrong.

Explaining technical concepts.  I may only know a small fraction of the information that a senior engineer knows, but I can explain that fractional amount in great detail.  This comes in handy when someone on staff needs to learn jasmine or angular.  In fact, I wrote a set of exercises to folks get their sea legs in our angular code base!

Research.  Writing new features is challenging, but a great deal of work happens before the writing starts, in the form of research.  Engineers often put off creating new features because they don’t want to stop everything in order to look up and vet libraries and methods.  With an English / history background, I jump at the chance to do a little research.  By explaining pros and cons of each option to my team, as well as answering their questions, I get our new features off the back burner and into our next release.

Pulse.  As a fairly new JavaScripter, I know all the best engineering podcasts and meetups around the city.  I know the latest information on the MIT Open Courseware and other course offerings.  I make it a point to keep a beat on the cutting-edge libraries so that I can offer these when our team is looking for new solutions.

Back to the original question: Is a senior engineer faster than 10 junior engineers?  Maybe.  But is a senior engineer worth 10 junior engineers?  I’m skeptical.  A senior person brings speed and knowledge, but also brings the baggage of comfort and a single perspective, often overlooking reasons why someone else might get tripped up on her/his UX, or spending hours on tired recruiting methods when s/he could simply contact a couple of key meetup organizers with the job announcement.

Junior engineers may be slow and overly methodical, but we’ve got grit and eagerness on our side.  When it comes down to it, I guess the only thing as good as 10 junior engineers is… well… 10 junior engineers.