The time I realized everyone was a lot better than I thought, I gave up .
I was doing great! I was winning! Then I wasn’t. Then I was losing. Then I was nearly crying and dragging myself up from the depth of emotions back to a draw. I was better than this guy! I could do it! I wasn’t going to lose! Then it was over. Handshake. Scoresheets signed.
My first rated chess game against an adult was over.
"You know what opening that was right?", I said. I’m gonna educate this patzer I thought.
"Yes, of course! The Vienna game – Steinitz gambit", he said.
I walked away wondering how he knew so much. Must have been a fluke I thought. I got this. I’m only 12! I’m gonna be a GM by the time I’m 15 and then world champion! I was 15 by the time I realized the significance of what he said.
I had my second real interview at 24 . I was nervous out of my mind and spent the night (okay days) before practicing and rehearsing social skills and topics of discussion. I was massively prepared! I was going to ace whatever coding challenge they threw at me! Palindromes?! Haha! I laugh in the face of palindromes! Linked lists?! I can link a list in my sleep. FizzBuzz?! Don’t make me chuckle.
There was no coding challenge.
I sailed through an interview about my work and tackled their trial run with ease. Their CEO was impressed and they flew me out to SF for a week in the office. He was less impressed when he realized that in person I’m incredibly awkward and socially inept. Despite my lack of social skills and bewilderment at whiteboarding during code reviews, I was able to impress the CEO with my speed and code quality. I thought I had this job for sure!
Then came the disappointing email.
We are sorry but at this time we cant extend you a full time offer. But we could off you some further contract work.
I fired back:
Thanks man, but I’m going to pursue full time opportunities
I didn’t want to waste my time on further contract work. I was an awesome coder! I would have a job in no time!
My third interview.
Could you explain Angular controllers to us?
umm… Yeah I guess… umm… umm… ummm… ummm
Then the disappointing (but not surprising) email:
We have decided to pursue other candidates
I have this palindrome problem we’d like you to work through
okay… umm… I think I need to reverse the string first? no sure about the performance of this though…
It is fine if you brute force first
ummm… how are are we for time? um… sorry I’m bombing. what did you say again?
Then the disappointing email:
We feel you are not right for us at this time
We want you to whiteboard for us
Umm I cant do that
We have decided that you aren’t a good fit right now. Send in your app again maybe when you have brushed up on your whiteboarding skills
And on and on it went like that until I gave up. I was disgusted with myself, disappointed, and depressed. How was I so bad at coding challenges? How was I so bad at interviews? How was it every one thought I was great at coding until they interviewed me? Why did I keep bombing so bad? I know I’m decent at coding. It must be the pressure. I’m terrible under pressure. I just suck at interviews.
Get Smarter Every day
One of my favorite YouTube channels is "Smarter Every day". In one experiment, they took a bike and reversed its steering, so that when you turned it to the left it went to the right and when you turned it to the right well, you get it.
The challenge was to ride it. It seems simple. The knowledge to ride the bike takes mere seconds to grasp – it is just like a normal bike but opposite. A funny thing happens though, you cant ride it; no matter how hard anyone tried they could not ride it. It takes Dustin (the creator of the channel) months to learn to ride it.
I think the most important take away from this is not that people cant ride a backwards bike; it is that we think we can ride a backwards bike. This fact reveals a whole class of invisible problems on the road to mastery of anything.
Knowledge != understanding, but because knowledge is how we articulate understanding we often confuse the two. When we are asked “how did you do that?” our response is to express the knowledge we have. We cant convey the understanding we have. This makes it very easy to fall into the trap that once you acquire the same knowledge that you have the same understanding. It is really easy to think you can ride a backwards bike.
The time I realized everyone was a lot better than I thought
Many tournaments after that first one…
I was winning! Then I wasn’t. Then I lost. This shouldn’t have happened! I was way better than this guy! I had spent so much time studying. I had become so good! So knowledgeable! But I lost.
That tournament was a disaster. I messed up so much and finished far below where I thought I would.
I thought, maybe I shouldn’t have drank the mountain dew. I shouldn’t have ate so many cookies. I should have followed my thinking process. I should have asked the TD to dim the lights. It must have been the lights.
When I sat down to analyze the game, I discovered something strange. This guy knew just as much as I did. He was familiar with the opening. His middlegame understanding was great. His planning was superior. His knowledge was just as good mine if not better.
It would have been easy to explain this away, to think he was underrated and that I was still as strong as I thought. But I had a revelation that day. I thought to myself, what if ratings are accurate? What if this guy really knew a lot more than me and what if I really wasn’t as strong as I thought? But if knowledge didn’t make people stronger what did?
I started to look more objectively at my games. I started to realize that my opponents very rarely beat me because of superior knowledge, they almost always beat me because they were more accurate, their technique was better, or they simply made one less mistake. I realized that I lost because of less understanding. There was a huge gap between how much I knew and my ability to put that knowledge into practice.
I begin to realize that technique wasn’t just a small part of chess, that it was actually the heart of it. Knowledge was easy, but actually really truly knowing something took a lot more time. I had spent years of my chess career focused on all the wrong things. I had devoured book after after book, spent hours upon hours reading but still found myself ranking below juniors that seemed to work way less hard than I did.
I had a lot of knowledge but little understanding and it was impossible to put any of that knowledge into practice because my lack of understanding would cause me to slip up. It was no use knowing at a high level when my lack of understanding would make it impossible to use that knowledge. It took the revelation that lots of people had a high level of knowledge to realize what I was missing was understanding. I knew a lot of chess but I didn’t understand nearly as much.
Why you suck
How quickly could you solve FizzBuzz without having ever seen it? Most of us like to think we could solve it instantly and most of us can. But if you had never seen it before could you really solve it in just a couple minutes?
It took a few interview failures for me to decide to practice. I started with very simple challenges. What I discovered shocked me, they took me a lot of time. It often took me half an hour or more to solve problems I had convinced myself I could solve in seconds. There was a huge disconnect between my knowledge and my understanding.
I had come out of interviews convinced that there must be something externally wrong because I was convinced that my knowledge was the same as understanding. I could figure out how to solve FizzBuzz in my sleep but there is a big gap between knowing how to solve a problem and being able to solve a problem.
You want to hack together a quick script. What language do you choose? I’d bet it is not the language you work with on your day job. I bet it is not even the best choice. If I was asked why I chose a language, without missing a beat I’d answer "Because I know it best". You would probably answer the same.
Now try to articulate why you know it better than another language. Is it because you know the syntax better? Is it because you know how to implement some pattern in it? Think about it for a moment and you will realize you probably know how to implement that pattern in many languages. And you probably know the syntax of other languages pretty well too. Then, why do you feel you know x language better?
I know many languages but when I hack something up I always use Ruby. Why? Because I understand Ruby. It isn’t that I know Ruby any better than say ES6. It is that I have all this surrounding knowledge, all these accumulated little things, that make working with Ruby easier, more productive, and generally less frustrating. If I say choose, for example, ES6, my brain knows that there will be friction. I might be able to write the same code in ES6 but getting to the point where it runs, where it works, where all my dependencies are there and working, all this might take me a lot longer in ES6.
Most of programming is invisible. Working with package managers, configuring and using editors, shortcuts, detecting stack problems and honing on the problem area, deciphering error messages, being able to detect when you are missing a semi-colon etc. These are all things that just happen, that your brain does automatically, that enable you to work faster, smarter, better.
When you lack understanding you can’t make use of your knowledge because you end up spending most of your time fighting against the unexpected. You keep forgetting the bike is backwards and have to catch your balance over and over.
When you learn a new stack you can see the things that were invisible. Suddenly things are frustrating again, you are hitting invisible pains everywhere; package manager explosions, cryptic error messages, libraries with unintuitive APIs, even documentation that reads differently. Learning a new stack makes you see the invisible again, for awhile, then we forget about it again.
Interviews are full of invisible knowledge, little things that turn FizzBuzz like challenges from a 30 minute headache to something done in seconds. In the typical interview challenge you have to;
1. Become familiar with the live coding tool or screensharing you are going to use.
Every interviewer is different, with different preferences, so welcome to a whole new world every time. If you are lucky this is a one time thing that you master in the first couple of minutes, but 40% of the time in the middle of the interview your tool is going to freeze up or crash and you are going to have to restart Skype, the Atom plugin, some web app etc.
2. Understand how to communicate with the interviewer.
Everyone has their own communication style and you will spend the first 10-15 minutes of any interview getting used to it. If you are lucky he will be a good interviewer and communicate what he wants from you but most will not. You will have to settle in and figure out whether he is a “show me” type, a “tell me” type, or a “confused and bewildered” by everything type.
3. You have to get comfortable and get in the zone.
Once you have done the previous two things, you have to ramp up, to get in the zone and get comfortable communicating and coding with the interviewer. I’m not going to lie, I have a huge ramp up time. It takes me a lot of time to warm up and be comfortable around a person. If my initial interview is with a different person than handles my coding challenge, I get incredibly nervous. By the time I have gotten comfortable I have burned through 30 minutes of time and I’m staring to look and feel like I’m a bad coder.
The previous two tasks can really interfere with getting in the zone, so protip, if you are interviewer eliminate them. Tell them ahead of time what to expect from the interview and what technology will be used. Eliminate the friction and pain point of that interview and your coder will perform optimally. Of course, better yet, hire your coders through a trial process.
4. You have to breakdown the problem.
When we encounter truly different problems, like a google type algorithm challenge we can recognize our lack of understanding. The trouble happens when we encounter stuff like FizzBuzz or "find the longest palindrome". They seem obvious to us and we never bother truly mastering how to break down a problem like it.
FizzBuzz can seem a lot like what we do everyday but it really isn’t. Most of my day is spent configuring dependencies, finding libraries, writing React views etc. FizzBuzz type problems are nothing like that. I know how to solve FizzBuzz but I don’t (at least not then) understand it. Not like I understand React or npm or redux reducers or Sinatra or Rack or Express.
Interview challenges are like a backwards bike. You can think you understand them because you know them. You don’t though. They look like the same thing but they are not. The disconnect between your knowledge and your understanding creates a ton of problems.
5. You have to be familiar with the tools needed to solve the problem.
This the hardest and most invisible part of interview challenges. I thought my knowledge had this covered perfectly but I didn’t. Most of the patterns you use to solve everyday programming challenges are not the same ones you will use to solve an interviewer’s challenge. There are all these invisible little things that we use to solve interview type challenges that most of the time we just forget about.
When was the last time you even reversed a string in a real project? You probably cant remember. Maybe it was days, maybe weeks, maybe months. So you google and read the docs – there goes 30 seconds and you haven’t even reversed a string yet.
How do you calculate permutations again? Oh that’s right, I did that once a long time ago. time 5 minutes.
Wait, can I use built in libraries? I can. Phew. I sorta know how to do that but there is no way I could figure it out on my own right now. 5 minutes and 30 seconds.
You haven’t even started on the real heart of the problem yet and the stress is building because you look and feel like an idiot that cant program.
We can use the built in libraries but we cant use eval. How do we avoid eval? Oh that is right, we use send! send is just a method on Object I think – it takes a symbol – but how do I dynamically calculate a symbol again? oh, we just take a string and to_sym it, god how did I forget that. wait, I bet send actually takes a string anyway. 20 minutes.
How did this take me so long to figure out? I’m an idiot. fuck.
This is how interviews go wrong. This is how you mess them up.
It is easy to think it’s easy
Last summer was tough, really tough. I had expected to sail through interviews but found myself struggling and imploding at every attempt. I kept failing. I hated myself. I doubted myself. I wondered if I was ever going to get my life under control. I worried about ever getting good enough at the “social things” to get a job and make a livable income. I was exhausted by contract work and I was exhausted by job hunting.
At first I blamed it on “nerves” or stressors. I thought if I just fixed the environmental factors that the next interview would go perfect. All I needed was to be rested, or prepared, or not drink too much caffeine before and then it would go smooth. But they didn’t, they kept going wrong.
I couldn’t understand it, I knew how to do things but under pressure I couldn’t. It took me several bad interviews to finally realize that I didn’t understand how to solve these type of interview challenges. I had the knowledge but not the understanding.
Just like in chess, 99% of these challenges take invisible skills. They took understanding I did not have. If the interviewers had asked me build a TodoMVC in React I would have flown through it. Find the longest palindrome type stuff tripped me up because I had little of the invisible knowledge needed to solve them effectively.
In an interview you cant eat up even 30 minutes on something like FizzBuzz. If you do then you now have another problem, you are running low on time. And running low on time creates more problems, it makes it harder to focus, it gives you less time to work through the rest of your problem. Now you are intentionally rushing and skipping points and trying to get to solution and wondering if the interviewer is looking for problem solving skills or a successful solution and too afraid to ask because that could eat up more time.
Just like in a chess game, the micro skills add up. If you had all the little skills it would be easy but without them it is kind of actually hard. Every little moment of friction adds up; 30 seconds of googling there, a struggle with a method there, trying to understand the performance implications there, remembering how to reverse a string there. It all adds up and before long it spirals out of control and you have lost the chess game, you have failed the interview.
Nerves are a symptom not the cause. Anyone gets nervous when their knowledge turns out to be a lack of understanding. You get stressed because you have keep falling off the backwards bike. Anyone would get frustrated and start to feel like an idiot. This seems obvious! But I cant seem to get it!
The trick is to not get angry, to not blame the failures on symptoms, to recognize the lack of understanding and to correct it. You have to realize a backwards bike is actually hard to ride. Then you pick yourself up and you practice every day for five minutes. Until one day, it clicks, and you finally get it. You are riding! Suddenly the knowledge becomes understanding, and “find the longest palindrome” becomes something you just do, it becomes like just riding a bike.
How I’m going to get better
I’m making a commitment to get better. To make interview challenges more intuitive. To master the fundamentals and make “find the longest palindrome” second nature. I want to get a job. I want to stop messing up and get my life on track. I want interview challenges to feel like riding a bike.
Programming is about data manipulation. Every problem is a challenge of taking one form of data (inputs) and transforming it into another form (outputs). I have broken it down into the following;
1. Math and Operators
I have to be honest I’m pretty bad at most forms of math. I haven’t touched a math textbook since I was like 14. There just hasn’t been a huge need for it. Interview challenges can often (but not usually) contain an element of math that simply goes over my head. Instead of being able to focus on the problem I end up distracted by the math. I need to fix that.
I will start with math as code and port it to variety of languages. From there I will dive into some more discrete math and then I have no idea. But I think “math as code” alone should iron out most of my issues.
2. Syntax and Language Features
Let’s be honest, how many of us know our programming languages inside and out? I’m going to make an effort to learn one language completely. I will master all its hidden gems and rely on it as my language of choice for interview challenges. Part of me wants to choose Haskell but I think I will focus on either Ruby or Python; both languages are simplistic and expressive enough that an interviewer is likely to get the gist of it even if they don’t know it.
3. Data Structures
In day to day programming you pretty much just push strings around inside of arrays. I’m ridiculously good at pushing strings around. I can use associative arrays with the best of them. I can map, reduce and filter in my sleep. Most other tasks are googled when they come up. Because it does not matter if it takes me an extra 30 seconds to reverse an array or an extra five minutes to implement a linked list because I just don’t do it often enough.
It is time to justify the time. I’m going to learn basic structures inside and out and all the means to operate on them. I will heavily rely on high level languages with raw implementations (i.e not in C) of their standard library. For Ruby there is Rubinus, for a LISP there is Clojure, and for JS I shall finally read the source of libraries like lodash. Eventually I will fully grasp the techniques for working with all the data structures!
If data structures are an analogy and algorithms are an analogy then they are probably like heart and soul or something. Who knows. What one does know is that they are extremely important in interview questions. You can probably understand bubble-sort after watching a quick dancing video but good luck trying to understand it on the spot and fast enough to not blow away all your time with the sand. Sure, you can brute force things, but more often than not, familiarity with algorithms is how you hit upon brute force solutions quickly. They have to be intuitive, it has to be like riding a bike. Right now most of my knowledge of algorithms is like my knowledge of riding a backwards bike, I lack a huge amount of understanding.
I will start with the most friendly book (so described I guess because of its friendly pictographs on the cover) on algorithms ever written, The Algorithm Design Manual a book I have heard of way too many times but never started. From there, I will tackle the world of coding challenges; HackerRank, Cracking The Coding Interview, Project Euler and more.
It is time to stop being terrible!
I didn’t give up chess forever. Several years after that tournament I returned to the board. ↩
This might seem odd, but is explained by the fact I started freelancing at 16 and founded a company at 17. I would highly recommend against this. In hindsight, trying to use work as an escape hatch was one of my worst decisions. If it had worked out I would have done very well, but most things fail. Always assume you will fail and operate from that point. Ask “what will my life be like if this doesn’t work out?” and operate from that. Not going to college is a risk the mentally ill and poverty stricken should not take. I assumed success and created a situation where failure was absolutely disastrous. But that is a story for another time ↩