You’re Not Solving Problems
When was the last time you solved a problem? Think about it — if you’re like most engineers, it has probably been a bit longer than you think. Here’s why: most of the time, when we think we’re solving a problem we’re actually not solving anything — we’re in the process of understanding the problem itself.
I learned to program in C++. Before I wrote my first program (calculating the area of a triangle or something to that effect) I had never seen a compiler error — let alone learned to decipher their meanings. Like most new developers, I spent a lot of time trying to understand exactly what the compiler was trying to tell me. At some point, I’d realize I left off an opening/closing curly bracket or missed a semicolon or something similarly trivial. Once I understood what the problem was, it was a 2 second fix! I spent almost no time at all solving the problem but spent a great deal of time understanding it.
Fast forward to today, I still find myself spending more time understanding problems (on a larger scale) rather than actually fixing them. I might write a bit of code to help gain insight (debug logging etc) but, it’s all in an effort to fully understand what’s happening — the fix is typically anticlimactic. This is one of the biggest skills most junior devs lack, and should seek to develop. Your strongest programming language or that game you have published in the App Store are relevant, but if they don’t aid in your ability to develop a strong problem solving acumen, your time might be better spent doing something else.
At ISL, we take mentoring and peer programming very seriously. Anyone who wants to be mentored, is being mentored. Apprentices and interns get mentors as part of the on-boarding process. Mentors are encouraged to peer program with their mentees — allowing the mentees to drive. Here’s where I tend to differ from my senior counterparts: I have my mentees do a little less coding than one might think. Obviously they still code, but I like to spend a bit more time helping them with understand problems — deeply.
I had a professor in college who would immediately make everyone in class turn their monitors backwards so that he could ensure that no one was typing as he was talking (even if they were actually programming). This used to infuriate me because I was genuinely trying to follow along and apply the lesson the the current week’s programming assignment. The problem was, typing code (or even notes) was taking up too much mental capacity and I was not able to fully absorb the theories he was trying to explain. I did not understand this until later in my career when I began teaching people to code.
When trying to explain a problem to a junior dev (or someone completely new to programming), their immediate instinct is to start typing. They want to get that code down before you walk away and leave them to their own devices. It’s certainly understandable — things seem much easier when someone experienced is sitting right next to you, explaining the ins and outs of the issue you’re facing and pointing out flaws in your logic. When that person walks away, you’re forced to think for yourself. That’s the point.
Confession: I’m not very smart. I don’t have what I would consider a “gift” for programming. My productivity is the sum of many many hours of struggle, contemplation and frustration. Don’t get me wrong, I’ve learned a thing or two over the course of my career (and still have a lot to learn), but most importantly, I’ve learned to think critically and try to find deeper understanding of problems because I know it will bring clarity to the (possible) solution(s).
When faced with a problem, a junior dev will hear what you say, then do what you tell them. A senior dev will understand what you tell them and do what’s best (or what they think is best, anyway). That’s the key, that’s where I’m trying to push junior people. This isn’t a binary condition — it’s a spectrum. Some junior devs are further along that spectrum than others and some senior devs aren’t as far along as they may think. One’s goal as a professional software developer should be to move along that spectrum so that you can understand problems on a fundamental level.
Some would argue that understanding the problem is a part of solving the it. I would argue that understanding the problem is certainly part of the problem solving process, but that you can never begin to truly solve a problem you don’t understand. Sure, you can drop in a solution, but that just means the problem was already solved for you and you were able to successfully utilize the solution — and that’s fine. This also implies that just because someone has already solved a problem doesn’t mean there’s no value in solving it for yourself. Who knows, you may indeed have a better solution.
Now, all of this is mental exercise…day before a launch, sure, drop in that (trusted, tested, performant, supported, minified) third party library and absolutely ship your code. Also, there’s a limit. You don’t necessarily have to work your way back to understanding the implementation details of garbage collection algorithms either — which may very well be a contributing factor. I’m also not advocating pushing your junior people into the deep end with no help in sight. We do, however, want to ensure we’re teaching them to fish. No matter your level of experience, let’s learn to take more time understanding root causes rather than implementing quick fixes that only disguise symptoms — it makes us all better professionals in the end.