Woman And computer
Human And Computer

Four console games you might like...

I only play a handful of games a year, so I haven't written a game review since my post on Oblivion a year ago. But since then I've played a few unusually good games, including one awesome PS/3 title last weekend, so I figured it's time for another review.

First, here's my gamer profile, so you can decide now whether reading any further is worth your time. I'm a console guy. I don't play games on a PC because I want the whole big-screen, comfy-couch immersion experience. Some of my favorite games in the past include Final Fantasy X, the Zelda franchise, the Mario franchise, Morrowind and Oblivion, Fable, Doom and Doom II (but not Quake or Unreal), and Donkey Kong 64. So there ya go. That's the kind of game I like. Adventure and RPG games, mostly, and FPS types only if they have sufficient atmosphere.

Here's the memorable stuff I've played lately.

Portal

Everyone's been buzzing about this Xbox-360 game: they all say you've gotta play it, really cool gameplay, blah blah blah, and to be honest it sounded boring as hell. Plus it's only available through a 3-game title called The Orange Box, and the other games on it don't interest me.

A friend of mine finally bought me the game, came over, and sat there and glared at me until I played it. That's one way to do it!

Summary: it rocks. Great gameplay, new game dynamics, genuinely funny storyline, and an unexpectedly cool ending song that's easy to play, if you happen to be a guitarist.

I stayed up all night and finished the game in one sitting, so it's not very long at all. Only takes about 90 minutes the second time through, maybe. I recommend playing it through a second time with the developer commentary turned on, especially if you're a programmer or designer, since it was all really interesting stuff.

The plot summary is pretty simple. You have to take a series of increasingly complex tests using a "portal gun" that can shoot linked orange and blue portals onto horizontal surfaces. Jumping through either portal shoots you out the other one, maintaining your momentum, which makes for some really cool suicide-jump situations and a whole lot of different puzzle types. A female computer voice messes with you throughout the tests. At the end of the last test, things go south, and you have to escape into the guts of the test facility, crawling through ducts and messy industrial back-rooms, to find the computer and destroy it. It's really the second half of the game that's the fun part; you have to use everything you learned during the testing phase and solve some tricky puzzles while not getting shot, falling into toxic waste, or dying in any number of other exciting ways.

The game is more or less flawless in its execution: it was smooth, well-designed, bug-free, and it stayed interesting without ever getting frustrating. It was a little masterpiece. Can't wait for the sequel.

Mario Galaxy

I asked my friend Andrew Wilson if he has a Wii yet, and he retorted: "NO, because I'm a grown-up!" Funny stuff. I'm assuming his wife won't let him buy one.

If you don't have a Wii, well, you're missing out. It's far from perfect – in fact the device itself is pretty weak, and is missing HD output, bluetooth and a number of other pretty important things. But its controllers really blow conventional controllers away. I've played one FPS on the Wii (Metroid Prime 3), and although the game itself was IMO a bit borderline, the controls were amazing. Going back to the XBox 360 or Playstation controllers feels totally rinky-dink, like I've traveled back to the 1980s and I'm using an Atari Joystick.

Plus it's actually true that non-gamers like the Wii, and the multiplayer party games wind up being a lot more fun than they are on other consoles. You can work up quite a sweat trying to beat the crap out of people in boxing matches or outrun them in olympic games. Fun stuff.

Anyway, I'd been kind of reluctant to play Super Mario Galaxy. Every time I saw someone playing it in a game store, they'd be running around teeny tiny planets like the ones in that book The Little Prince, and it looked like it was going to be absolutely nauseating. And I mean literally nauseating, in the motion-sickness sense. It just didn't look anywhere near as fun as previous classic Mario titles (Mario 64 comes to mind – I just replayed that on my Nintendo DS and loved it just as much as ten years ago.)

But I figured I'd give it a try, and boy, was I wrong about it. Mario Galaxy is arguably the best Mario title since the original Super Mario Bros. arcade game. Nintendo just nailed it, across the board: well-balanced gameplay with lots of variety, superb level design, gorgeous sets, and probably the best music ever from a Mario franchise game – check out this orchestra recording the Gusty Garden Galaxy Theme, for instance. It's just one of several equally awesome pieces written for the game. (I also particularly liked the Good Egg Galaxy theme, the "Teresa Waltz" in the Ghostly Galaxy, the Bowser Battle music, the Buoy Base theme, and the Disney-esque Observatory waltz. But almost all the music was worth listening to, and I can't wait until the soundtrack is available.)

The game has oodles of atmosphere. You can practically feel the wind in the Gusty Garden Galaxy. You can almost smell the honey in the Honeyhive Galaxy. In the Beach Bowl you feel the sun on your back and smell the surf. It's really weird, actually – I've never played a game before that made it feel like all five senses were in play the way this game does.

I experienced none of the motion-sickness or discomfort I had been dreading. You get used to the gravity surprisingly fast, and before long it doesn't matter what combination of camera angle and orientation you happen to have active – you just keep on running, jumping, and smashing things, upside-down and backwards. It's the most truly three-dimensional game environment I've ever played.

My favorite part of the game, which I played over and over just for the effect, was probably the first Battlerock level. The music is reminiscent of Mars from Holst's The Planets, and builds up steadily while you make your way towards this huge rock in the distance. As you get closer you realize it's sort of like the Death Star, and it's shooting at you like mad as the music builds to a climax. Great level!

One of the big turn-offs for me in the Mario and Zelda franchises has been overly-tough boss battles. I think Twilight Princess and Mario Galaxy have both finally dialed it right: the boss fights can be challenging but are achievable without having to take a two-hour time-out from the plotline just to practice some crazy move, as has been the case in so many past titles.

Anyway, the game made a fanboy out of me, so, you know, take all this with a grain of salt. You might like it, you might not. I thought it was great.

Zelda Twilight Princess

I played Twilight Princess last year – I can't remember exactly when, but it feels like a long time ago. Great game, though; if you haven't played it and you like the genre, you need to get your hands on a GameCube or a Wii. I played TP on my old GameCube, since it was before I owned a Wii, and I was highly skeptical of the Wii controls for that kind of game, at the time. I couldn't imagine holding my arm out for ten minutes trying to keep my bow steady. (This was long before I learned that the Wii controls often work best when your wrists and elbows are on the couch and you're just flicking the Wiimotes around like laser pointers.)

I originally wasn't going to write a long review of this game, since it's not exactly making news headlines anymore. I did think it was just as good as Ocarina of Time and Wind Waker, but not any better. In fact, I think I might have enjoyed Wind Waker a little more than Twilight Princess. That said, TP was one of the best games of the past ten years, and had some truly groundbreaking gameplay and atmospheric elements.

The more I think about it, the more I'm remembering how much fun I had with it. So it gets a spot in my most-recommended list for the past year.

A few scenes still stand out after nearly a year. Flying the big Nazgul-mount-ish monster upriver while getting shot at from the banks played like a scene out of Peter Jackson's Lord of the Rings. The minigame in the canoe coming back downriver was loads of fun. The burning bridge and fall into Lake Hylia were really cool. Searching for bugs for that wacked-out little girl was... weird, but fun. The horseback riding and combat were both completely new and exciting. And I just about died laughing when I wrecked my first wild boar.

The game has an eerie and heartrending central climax, "Midna's Desperate Hour." You're stuck in wolf form, carrying your dying friend Midna to the castle to try to save her while some really sad music plays, and it just goes from bad to worse. You start off having to run through town in broad daylight as a wolf for the first time, and the townspeople are all running from you screaming in horror, which doesn't make you feel any better about the situation. Then you have to make your way across the most bleak, windswept rooftops imaginable, buffeted by this sort of ash-storm, and then, well, let's just say they're setting you up to stab your heart out when you get to the castle. It's pretty agonizing. The mood does eventually pick up, though, and eventually you do beat the bad guy and save the day.

If you haven't played it, you should give it a try. In some sense it's just another Zelda game with all the expected elements, including lonely temples filled with puzzles, little towns filled with bizarre characters, the usual power-ups and mini-games, and the classic heart-container scheme. But it gets major points for having a dramatic sweep and story-arc not really present in previous Zelda titles. It's also got much more achievable boss battles, so you can finish the game without ever getting insanely frustrated.

Now I'm making myself want to go back and play it again, so I'll shut up about it.

Uncharted: Drake's Fortune

I just played Drake's Fortune last weekend. It's the reason I wrote this blog entry, actually. In my humble and totally biased fanboy opinion, you should run out and buy it right now, along with a PS/3 and a bigger TV.

I saw a commercial for the game last year and thought: "Hey, that almost looks like a game that could induce me to buy a Playstation 3. Almost." But I was worried about the whole Blu-Ray vs. HD-DVD thing, and PS/3s used to be kind of steep (they were, what, like six hundred bucks initially?), and I just kinda dragged my feet on the whole issue forever, as I suspect most of you have been doing.

Then Blu-Ray won the war a couple weeks ago, all rather suddenly and unexpectedly, and I thought, hey, this might be a good time to replace my ancient TV and get myself a PS/3, so I can finally drag myself out of the non-HD dark ages. So I went big-screen shopping, and unlike for every other TV I've bought in the past, I decided not to cheap out this time. I wound up buying a Panasonic 58" 1080p plasma HDTV, which after lots of research and staring at screens in stores, narrowly beat out the Sony Bravia XBR4 52" 1080p LCD HDTV. They're both great products, but the plasma still beats the LCD for gaming.

The 58-inch plasma is jaw-droppingly awesome. I replaced my Comcast box with one of their HD-DVRs, and it works great but has almost no space for recording shows, so at some point I'll probably have to pick up an HD Tivo. It's too bad, really, since I have the lifetime-membership Tivo, and I'll almost certainly have to switch to paying a monthly fee if I upgrade to the HD version, since I missed the promotion window when they came out. But you really do need the extra space, so the Comcast one is going to have to go. In the meantime, the HD channels look great, and they only cost me about ten bucks more than the package I already had, so it was well worth it.

Let me tell you: nothing, nothing I've seen so far on my new screen, not Blu-Ray discs, not HD channels, not Oblivion on the XBox 360, nothing can compare to the visual feast provided by Drake's Fortune. It's reportedly only 720p, but it looks like it's 1080p and then some. I took a bunch of pictures of it while I was playing, cheesy ones on my iphone that I'm embarrassed to upload, but it had so many stop-and-stare areas that I just kept taking pics.

Anyway, visuals aside, the game itself is sort of a cross between Tomb Raider (the original, which was pretty fun) and Gears of War, which I've never played, but people say Drake's Fortune has similar combat mechanics. And it's a bit like the recent horror movie The Descent towards the end. Yeah. I didn't see that element coming, but it was pretty darn cool. And scary.

The game is short and linear: an interactive movie, essentially. I took my time with it and still finished in about 13 hours. There are some puzzles, but not too many, and none of them are even remotely difficult to figure out. Which is good, I suppose; in my old age I don't like to spend too long on any one puzzle, so I'm pretty quick to go look online for hints if I get stuck. Didn't have to do that for this game, which helped increase the immersiveness.

The game starts off a little slow, to be honest, and after the first hour I was starting to worry that it would suck. You have to stick it out until you parachute onto the second island, after which it gradually picks up the pace until it feels like it's a flat-out race to the finish.

Most of the game, especially the latter half, revolves around the combat, nearly all of which is against modern-day pirates. You have to get good at ducking behind walls and fast aiming to have a hope of surviving (although trust me on this one, if a non-FPS gamer like me can master it in a few hours, you can too). I found the combat to be loads of fun, and I'm getting ready to play the game through again just for that. You run across a good selection of weapons, including a nifty Dragon Sniper rifle, and you have to make tough decisions about what to carry with you since you've got limited inventory space: one handgun and one rifle or shotgun, basically, plus a little ammo.

The voice acting is really good, much better than it was in Oblivion, although I'm sure it was easier since the game is shorter and there are fewer characters. The lines are a little cheesy at first, but either the writing got better as the game progressed, or I just got used to it. Either way, by mid-game it felt pretty believable. In fact I laughed a lot at the characters' reactions. The main character, uh, mumble Drake, I forget his first name, says exactly what I would have said, the first time a grenade lands next to him. It's not repeatable here. The swearing/profanity in the game isn't over-the-top, but they use it effectively now and then for humor value.

The AIs are great, and for a lot of the game you've got at least one friend following you around and helping you fight stuff or solve puzzles. They almost feel like real people, and they're nowhere near the nuisances NPC helpers have been in hundreds of games in the past.

The generator-room sequence is just plain scary. I've played scarier games, sure – Fatal Frame comes to mind – but this one really had my pulse going towards the end of the game. For an hour, at least, until I finally made it out of there. I'm lucky I didn't keel over.

There are a few fast-paced movie-like combat sequences thrown in. There's one especially memorable scene where you're riding shotgun in a Jeep, and you have to shoot at bad guys coming after you while you're racing through the jungle. Cool stuff. The whole feel of the game is very Indiana Jones, actually. Naughty Dog did a great job with it across the board.

And the visuals – well, they simply defy any possibility of describing them here. Steaming tropical jungles, crumbling Spanish fortresses, foamy waves crashing against the rocks a hundred feet below you, realistic character motion and rendering – the game is sumptuous, no better word for it.

You really have to play this game. You only need to set aside one day for it, so you might as well check it out!

Some final thoughts

I pretty much bought my XBox 360 for Oblivion, although it wound up being my DVD player for a couple years after my Sony player died. It didn't matter, though, since Oblivion was good enough to warrant the purchase of an XBox 360. And I did find one or two other 360 titles that were fun (e.g. Kameo: Elements of Power, a fun but short romp from ex-Rareware, my ex-favorite game studio.) I'm hanging on to my 360 specifically so I can play Fable 2 this holiday season. The original Fable was lots of fun, and had a cool werewolf scene I'll remember to my dying day. I hope the sequel is every bit as good.

But I'm clearly someone who doesn't need much incentive to buy a game console.

I pretty much bought my PS/3 for Drake's Fortune, hoping it would be worth it, although it's also nice to have a Blu-Ray player. I'd have to say Drake's Fortune doesn't singlehandedly justify the purchase of a PS/3 for gaming purposes, but it does illustrate the potential of the platform, and I think there are tons of great titles to come. For a while most of the good games are likely to be ports that are also available on the 360, but they say the PS/3 has a lot more parallel-processing power, so as game developers learn to take advantage of it I'm guessing the PS/3 eventually gets the edge.

It's still early-adopter material, though, so if you already own a Blu-Ray player, a PS/3 may not be worth it this year. Drake's Fortune will still be a fun game next year, and will be a lot cheaper than its current $60 price tag.

And with that, it's a wrap! Looking forward to seeing your game suggestions in the comments.

Get that job at Google

I've been meaning to write up some tips on interviewing at Google for a good long time now. I keep putting it off, though, because it's going to make you mad. Probably. For some statistical definition of "you", it's very likely to upset you.

Why? Because... well, here, I wrote a little ditty about it:

Hey man, I don't know that stuff
Stevey's talking aboooooout
If my boss thinks it's important
I'm gonna get fiiiiiiiiiired
Oooh yeah baaaby baaaay-beeeeee....

I didn't realize this was such a typical reaction back when I first started writing about interviewing, way back at other companies. Boy-o-howdy did I find out in a hurry.

See, it goes like this:

Me: blah blah blah, I like asking question X in interviews, blah blah blah...

You: Question X? Oh man, I haven't heard about X since college! I've never needed it for my job! He asks that in interviews? But that means someone out there thinks it's important to know, and, and... I don't know it! If they detect my ignorance, not only will I be summarily fired for incompetence without so much as a thank-you, I will also be unemployable by people who ask question X! If people listen to Stevey, that will be everyone! I will become homeless and destitute! For not knowing something I've never needed before! This is horrible! I would attack X itself, except that I do not want to pick up a book and figure enough out about it to discredit it. Clearly I must yell a lot about how stupid Stevey is so that nobody will listen to him!

Me: So in conclusion, blah blah... huh? Did you say "fired"? "Destitute?" What are you talking about?

You: Aaaaaaauuuggh!!! *stab* *stab* *stab*

Me: That's it. I'm never talking about interviewing again.

It doesn't matter what X is, either. It's arbitrary. I could say: "I really enjoy asking the candidate (their name) in interviews", and people would still freak out, on account of insecurity about either interviewing in general or their knowledge of their own name, hopefully the former.

But THEN, time passes, and interview candidates come and go, and we always wind up saying: "Gosh, we sure wish that obviously smart person had prepared a little better for his or her interviews. Is there any way we can help future candidates out with some tips?"

And then nobody actually does anything, because we're all afraid of getting stabbed violently by People Who Don't Know X.

I considered giving out a set of tips in which I actually use variable names like X, rather than real subjects, but decided that in the resultant vacuum, everyone would get upset. Otherwise that approach seemed pretty good, as long as I published under a pseudonym.

In the end, people really need the tips, regardless of how many feelings get hurt along the way. So rather than skirt around the issues, I'm going to give you a few mandatory substitutions for X along with a fair amount of general interview-prep information.

Caveats and Disclaimers

This blog is not endorsed by Google. Google doesn't know I'm publishing these tips. It's just between you and me, OK? Don't tell them I prepped you. Just go kick ass on your interviews and we'll be square.

I'm only talking about general software engineering positions, and interviews for those positions.

These tips are actually generic; there's nothing specific to Google vs. any other software company. I could have been writing these tips about my first software job 20 years ago. That implies that these tips are also timeless, at least for the span of our careers.

These tips obviously won't get you a job on their own. My hope is that by following them you will perform your very best during the interviews.

Oh, and um, why Google?

Oho! Why Google, you ask? Well let's just have that dialog right up front, shall we?

You: Should I work at Google? Is it all they say it is, and more? Will I be serenely happy there? Should I apply immediately?

Me: Yes.

You: To which ques... wait, what do you mean by "Yes?" I didn't even say who I am!

Me: Dude, the answer is Yes. (You may be a woman, but I'm still calling you Dude.)

You: But... but... I am paralyzed by inertia! And I feel a certain comfort level at my current company, or at least I have become relatively inured to the discomfort. I know people here and nobody at Google! I would have to learn Google's build system and technology and stuff! I have no credibility, no reputation there – I would have to start over virtually from scratch! I waited too long, there's no upside! I'm afraaaaaaid!

Me: DUDE. The answer is Yes already, OK? It's an invariant. Everyone else who came to Google was in the exact same position as you are, modulo a handful of famous people with beards that put Gandalf's to shame, but they're a very tiny minority. Everyone who applied had the same reasons for not applying as you do. And everyone here says: "GOSH, I SURE AM HAPPY I CAME HERE!" So just apply already. But prep first.

You: But what if I get a mistrial? I might be smart and qualified, but for some random reason I may do poorly in the interviews and not get an offer! That would be a huge blow to my ego! I would rather pass up the opportunity altogether than have a chance of failure!

Me: Yeah, that's at least partly true. Heck, I kinda didn't make it in on my first attempt, but I begged like a street dog until they gave me a second round of interviews. I caught them in a weak moment. And the second time around, I prepared, and did much better.

The thing is, Google has a well-known false negative rate, which means we sometimes turn away qualified people, because that's considered better than sometimes hiring unqualified people. This is actually an industry-wide thing, but the dial gets turned differently at different companies. At Google the false-negative rate is pretty high. I don't know what it is, but I do know a lot of smart, qualified people who've not made it through our interviews. It's a bummer.

But the really important takeaway is this: if you don't get an offer, you may still be qualified to work here. So it needn't be a blow to your ego at all!

As far as anyone I know can tell, false negatives are completely random, and are unrelated to your skills or qualifications. They can happen from a variety of factors, including but not limited to:

  1. you're having an off day
  2. one or more of your interviewers is having an off day
  3. there were communication issues invisible to you and/or one or more of the interviewers
  4. you got unlucky and got an Interview Anti-Loop
Oh no, not the Interview Anti-Loop!

Yes, I'm afraid you have to worry about this.

What is it, you ask? Well, back when I was at Amazon, we did (and they undoubtedly still do) a LOT of soul-searching about this exact problem. We eventually concluded that every single employee E at Amazon has at least one "Interview Anti-Loop": a set of other employees S who would not hire E. The root cause is important for you to understand when you're going into interviews, so I'll tell you a little about what I've found over the years.

First, you can't tell interviewers what's important. Not at any company. Not unless they're specifically asking you for advice. You have a very narrow window of perhaps one year after an engineer graduates from college to inculcate them in the art of interviewing, after which the window closes and they believe they are a "good interviewer" and they don't need to change their questions, their question styles, their interviewing style, or their feedback style, ever again.

It's a problem. But I've had my hand bitten enough times that I just don't try anymore.

Second problem: every "experienced" interviewer has a set of pet subjects and possibly specific questions that he or she feels is an accurate gauge of a candidate's abilities. The question sets for any two interviewers can be widely different and even entirely non-overlapping.

A classic example found everywhere is: Interviewer A always asks about C++ trivia, filesystems, network protocols and discrete math. Interviewer B always asks about Java trivia, design patterns, unit testing, web frameworks, and software project management. For any given candidate with both A and B on the interview loop, A and B are likely to give very different votes. A and B would probably not even hire each other, given a chance, but they both happened to go through interviewer C, who asked them both about data structures, unix utilities, and processes versus threads, and A and B both happened to squeak by.

That's almost always what happens when you get an offer from a tech company. You just happened to squeak by. Because of the inherently flawed nature of the interviewing process, it's highly likely that someone on the loop will be unimpressed with you, even if you are Alan Turing. Especially if you're Alan Turing, in fact, since it means you obviously don't know C++.

The bottom line is, if you go to an interview at any software company, you should plan for the contingency that you might get genuinely unlucky, and wind up with one or more people from your Interview Anti-Loop on your interview loop. If this happens, you will struggle, then be told that you were not a fit at this time, and then you will feel bad. Just as long as you don't feel meta-bad, everything is OK. You should feel good that you feel bad after this happens, because hey, it means you're human.

And then you should wait 6-12 months and re-apply. That's pretty much the best solution we (or anyone else I know of) could come up with for the false-negative problem. We wipe the slate clean and start over again. There are lots of people here who got in on their second or third attempt, and they're kicking butt.

You can too.

OK, I feel better about potentially not getting hired

Good! So let's get on to those tips, then.

If you've been following along very closely, you'll have realized that I'm interviewer D. Meaning that my personal set of pet questions and topics is just my own, and it's no better or worse than anyone else's. So I can't tell you what it is, no matter how much I'd like to, because I'll offend interviewers A through X who have slightly different working sets.

Instead, I want to prep you for some general topics that I believe are shared by the majority of tech interviewers at Google-like companies. Roughly speaking, this means the company builds a lot of their own software and does a lot of distributed computing. There are other tech-company footprints, the opposite end of the spectrum being companies that outsource everything to consultants and try to use as much third-party software as possible. My tips will be useful only to the extent that the company resembles Google.

So you might as well make it Google, eh?

First, let's talk about non-technical prep.

The Warm-Up

Nobody goes into a boxing match cold. Lesson: you should bring your boxing gloves to the interview. No, wait, sorry, I mean: warm up beforehand!

How do you warm up? Basically there is short-term and long-term warming up, and you should do both.

Long-term warming up means: study and practice for a week or two before the interview. You want your mind to be in the general "mode" of problem solving on whiteboards. If you can do it on a whiteboard, every other medium (laptop, shared network document, whatever) is a cakewalk. So plan for the whiteboard.

Short-term warming up means: get lots of rest the night before, and then do intense, fast-paced warm-ups the morning of the interview.

The two best long-term warm-ups I know of are:

1) Study a data-structures and algorithms book. Why? Because it is the most likely to help you beef up on problem identification. Many interviewers are happy when you understand the broad class of question they're asking without explanation. For instance, if they ask you about coloring U.S. states in different colors, you get major bonus points if you recognize it as a graph-coloring problem, even if you don't actually remember exactly how graph-coloring works.

And if you do remember how it works, then you can probably whip through the answer pretty quickly. So your best bet, interview-prep wise, is to practice the art of recognizing that certain problem classes are best solved with certain algorithms and data structures.

My absolute favorite for this kind of interview preparation is Steven Skiena's The Algorithm Design Manual. More than any other book it helped me understand just how astonishingly commonplace (and important) graph problems are – they should be part of every working programmer's toolkit. The book also covers basic data structures and sorting algorithms, which is a nice bonus. But the gold mine is the second half of the book, which is a sort of encyclopedia of 1-pagers on zillions of useful problems and various ways to solve them, without too much detail. Almost every 1-pager has a simple picture, making it easy to remember. This is a great way to learn how to identify hundreds of problem types.

Other interviewers I know recommend Introduction to Algorithms. It's a true classic and an invaluable resource, but it will probably take you more than 2 weeks to get through it. But if you want to come into your interviews prepped, then consider deferring your application until you've made your way through that book.

2) Have a friend interview you. The friend should ask you a random interview question, and you should go write it on the board. You should keep going until it is complete, no matter how tired or lazy you feel. Do this as much as you can possibly tolerate.

I didn't do these two types of preparation before my first Google interview, and I was absolutely shocked at how bad at whiteboard coding I had become since I had last interviewed seven years prior. It's hard! And I also had forgotten a bunch of algorithms and data structures that I used to know, or at least had heard of.

Going through these exercises for a week prepped me mightily for my second round of Google interviews, and I did way, way better. It made all the difference.

As for short-term preparation, all you can really do is make sure you are as alert and warmed up as possible. Don't go in cold. Solve a few problems and read through your study books. Drink some coffee: it actually helps you think faster, believe it or not. Make sure you spend at least an hour practicing immediately before you walk into the interview. Treat it like a sports game or a music recital, or heck, an exam: if you go in warmed up you'll give your best performance.

Mental Prep

So! You're a hotshot programmer with a long list of accomplishments. Time to forget about all that and focus on interview survival.

You should go in humble, open-minded, and focused.

If you come across as arrogant, then people will question whether they want to work with you. The best way to appear arrogant is to question the validity of the interviewer's question – it really ticks them off, as I pointed out earlier on. Remember how I said you can't tell an interviewer how to interview? Well, that's especially true if you're a candidate.

So don't ask: "gosh, are algorithms really all that important? do you ever need to do that kind of thing in real life? I've never had to do that kind of stuff." You'll just get rejected, so don't say that kind of thing. Treat every question as legitimate, even if you are frustrated that you don't know the answer.

Feel free to ask for help or hints if you're stuck. Some interviewers take points off for that, but occasionally it will get you past some hurdle and give you a good performance on what would have otherwise been a horrible stony half-hour silence.

Don't say "choo choo choo" when you're "thinking".

Don't try to change the subject and answer a different question. Don't try to divert the interviewer from asking you a question by telling war stories. Don't try to bluff your interviewer. You should focus on each problem they're giving you and make your best effort to answer it fully.

Some interviewers will not ask you to write code, but they will expect you to start writing code on the whiteboard at some point during your answer. They will give you hints but won't necessarily come right out and say: "I want you to write some code on the board now." If in doubt, you should ask them if they would like to see code.

Interviewers have vastly different expectations about code. I personally don't care about syntax (unless you write something that could obviously never work in any programming language, at which point I will dive in and verify that you are not, in fact, a circus clown and that it was an honest mistake). But some interviewers are really picky about syntax, and some will even silently mark you down for missing a semicolon or a curly brace, without telling you. I think of these interviewers as – well, it's a technical term that rhymes with "bass soles", but they think of themselves as brilliant technical evaluators, and there's no way to tell them otherwise.

So ask. Ask if they care about syntax, and if they do, try to get it right. Look over your code carefully from different angles and distances. Pretend it's someone else's code and you're tasked with finding bugs in it. You'd be amazed at what you can miss when you're standing 2 feet from a whiteboard with an interviewer staring at your shoulder blades.

It's OK (and highly encouraged) to ask a few clarifying questions, and occasionally verify with the interviewer that you're on the track they want you to be on. Some interviewers will mark you down if you just jump up and start coding, even if you get the code right. They'll say you didn't think carefully first, and you're one of those "let's not do any design" type cowboys. So even if you think you know the answer to the problem, ask some questions and talk about the approach you'll take a little before diving in.

On the flip side, don't take too long before actually solving the problem, or some interviewers will give you a delay-of-game penalty. Try to move (and write) quickly, since often interviewers want to get through more than one question during the interview, and if you solve the first one too slowly then they'll be out of time. They'll mark you down because they couldn't get a full picture of your skills. The benefit of the doubt is rarely given in interviewing.

One last non-technical tip: bring your own whiteboard dry-erase markers. They sell pencil-thin ones at office supply stores, whereas most companies (including Google) tend to stock the fat kind. The thin ones turn your whiteboard from a 480i standard-definition tube into a 58-inch 1080p HD plasma screen. You need all the help you can get, and free whiteboard space is a real blessing.

You should also practice whiteboard space-management skills, such as not starting on the right and coding down into the lower-right corner in Teeny Unreadable Font. Your interviewer will not be impressed. Amusingly, although it always irks me when people do this, I did it during my interviews, too. Just be aware of it!

Oh, and don't let the marker dry out while you're standing there waving it. I'm tellin' ya: you want minimal distractions during the interview, and that one is surprisingly common.

OK, that should be good for non-tech tips. On to X, for some value of X! Don't stab me!

Tech Prep Tips

The best tip is: go get a computer science degree. The more computer science you have, the better. You don't have to have a CS degree, but it helps. It doesn't have to be an advanced degree, but that helps too.

However, you're probably thinking of applying to Google a little sooner than 2 to 8 years from now, so here are some shorter-term tips for you.

Algorithm Complexity: you need to know Big-O. It's a must. If you struggle with basic big-O complexity analysis, then you are almost guaranteed not to get hired. It's, like, one chapter in the beginning of one theory of computation book, so just go read it. You can do it.

Sorting: know how to sort. Don't do bubble-sort. You should know the details of at least one n*log(n) sorting algorithm, preferably two (say, quicksort and merge sort). Merge sort can be highly useful in situations where quicksort is impractical, so take a look at it.

For God's sake, don't try sorting a linked list during the interview.

Hashtables: hashtables are arguably the single most important data structure known to mankind. You absolutely have to know how they work. Again, it's like one chapter in one data structures book, so just go read about them. You should be able to implement one using only arrays in your favorite language, in about the space of one interview.

Trees: you should know about trees. I'm tellin' ya: this is basic stuff, and it's embarrassing to bring it up, but some of you out there don't know basic tree construction, traversal and manipulation algorithms. You should be familiar with binary trees, n-ary trees, and trie-trees at the very very least. Trees are probably the best source of practice problems for your long-term warmup exercises.

You should be familiar with at least one flavor of balanced binary tree, whether it's a red/black tree, a splay tree or an AVL tree. You should actually know how it's implemented.

You should know about tree traversal algorithms: BFS and DFS, and know the difference between inorder, postorder and preorder.

You might not use trees much day-to-day, but if so, it's because you're avoiding tree problems. You won't need to do that anymore once you know how they work. Study up!

Graphs

Graphs are, like, really really important. More than you think. Even if you already think they're important, it's probably more than you think.

There are three basic ways to represent a graph in memory (objects and pointers, matrix, and adjacency list), and you should familiarize yourself with each representation and its pros and cons.

You should know the basic graph traversal algorithms: breadth-first search and depth-first search. You should know their computational complexity, their tradeoffs, and how to implement them in real code.

You should try to study up on fancier algorithms, such as Dijkstra and A*, if you get a chance. They're really great for just about anything, from game programming to distributed computing to you name it. You should know them.

Whenever someone gives you a problem, think graphs. They are the most fundamental and flexible way of representing any kind of a relationship, so it's about a 50-50 shot that any interesting design problem has a graph involved in it. Make absolutely sure you can't think of a way to solve it using graphs before moving on to other solution types. This tip is important!

Other data structures

You should study up on as many other data structures and algorithms as you can fit in that big noggin of yours. You should especially know about the most famous classes of NP-complete problems, such as traveling salesman and the knapsack problem, and be able to recognize them when an interviewer asks you them in disguise.

You should find out what NP-complete means.

Basically, hit that data structures book hard, and try to retain as much of it as you can, and you can't go wrong.

Math

Some interviewers ask basic discrete math questions. This is more prevalent at Google than at other places I've been, and I consider it a Good Thing, even though I'm not particularly good at discrete math. We're surrounded by counting problems, probability problems, and other Discrete Math 101 situations, and those innumerate among us blithely hack around them without knowing what we're doing.

Don't get mad if the interviewer asks math questions. Do your best. Your best will be a heck of a lot better if you spend some time before the interview refreshing your memory on (or teaching yourself) the essentials of combinatorics and probability. You should be familiar with n-choose-k problems and their ilk – the more the better.

I know, I know, you're short on time. But this tip can really help make the difference between a "we're not sure" and a "let's hire her". And it's actually not all that bad – discrete math doesn't use much of the high-school math you studied and forgot. It starts back with elementary-school math and builds up from there, so you can probably pick up what you need for interviews in a couple of days of intense study.

Sadly, I don't have a good recommendation for a Discrete Math book, so if you do, please mention it in the comments. Thanks.

Operating Systems

This is just a plug, from me, for you to know about processes, threads and concurrency issues. A lot of interviewers ask about that stuff, and it's pretty fundamental, so you should know it. Know about locks and mutexes and semaphores and monitors and how they work. Know about deadlock and livelock and how to avoid them. Know what resources a processes needs, and a thread needs, and how context switching works, and how it's initiated by the operating system and underlying hardware. Know a little about scheduling. The world is rapidly moving towards multi-core, and you'll be a dinosaur in a real hurry if you don't understand the fundamentals of "modern" (which is to say, "kinda broken") concurrency constructs.

The best, most practical book I've ever personally read on the subject is Doug Lea's Concurrent Programming in Java. It got me the most bang per page. There are obviously lots of other books on concurrency. I'd avoid the academic ones and focus on the practical stuff, since it's most likely to get asked in interviews.

Coding

You should know at least one programming language really well, and it should preferably be C++ or Java. C# is OK too, since it's pretty similar to Java. You will be expected to write some code in at least some of your interviews. You will be expected to know a fair amount of detail about your favorite programming language.

Other Stuff

Because of the rules I outlined above, it's still possible that you'll get Interviewer A, and none of the stuff you've studied from these tips will be directly useful (except being warmed up.) If so, just do your best. Worst case, you can always come back in 6-12 months, right? Might seem like a long time, but I assure you it will go by in a flash.

The stuff I've covered is actually mostly red-flags: stuff that really worries people if you don't know it. The discrete math is potentially optional, but somewhat risky if you don't know the first thing about it. Everything else I've mentioned you should know cold, and then you'll at least be prepped for the baseline interview level. It could be a lot harder than that, depending on the interviewer, or it could be easy.

It just depends on how lucky you are. Are you feeling lucky? Then give it a try!

Send me your resume

I'll probably batch up any resume submissions people send me and submit them weekly. In the meantime, study up! You have a lot of warming up to do. Real-world work makes you rusty.

I hope this was helpful. Let the flames begin, etc. Yawn.

Get that job at Google

I've been meaning to write up some tips on interviewing at Google for a good long time now. I keep putting it off, though, because it's going to make you mad. Probably. For some statistical definition of "you", it's very likely to upset you.

Why? Because... well, here, I wrote a little ditty about it:

Hey man, I don't know that stuff
Stevey's talking aboooooout
If my boss thinks it's important
I'm gonna get fiiiiiiiiiired
Oooh yeah baaaby baaaay-beeeeee....

I didn't realize this was such a typical reaction back when I first started writing about interviewing, way back at other companies. Boy-o-howdy did I find out in a hurry.

See, it goes like this:

Me: blah blah blah, I like asking question X in interviews, blah blah blah...

You: Question X? Oh man, I haven't heard about X since college! I've never needed it for my job! He asks that in interviews? But that means someone out there thinks it's important to know, and, and... I don't know it! If they detect my ignorance, not only will I be summarily fired for incompetence without so much as a thank-you, I will also be unemployable by people who ask question X! If people listen to Stevey, that will be everyone! I will become homeless and destitute! For not knowing something I've never needed before! This is horrible! I would attack X itself, except that I do not want to pick up a book and figure enough out about it to discredit it. Clearly I must yell a lot about how stupid Stevey is so that nobody will listen to him!

Me: So in conclusion, blah blah... huh? Did you say "fired"? "Destitute?" What are you talking about?

You: Aaaaaaauuuggh!!! *stab* *stab* *stab*

Me: That's it. I'm never talking about interviewing again.

It doesn't matter what X is, either. It's arbitrary. I could say: "I really enjoy asking the candidate (their name) in interviews", and people would still freak out, on account of insecurity about either interviewing in general or their knowledge of their own name, hopefully the former.

But THEN, time passes, and interview candidates come and go, and we always wind up saying: "Gosh, we sure wish that obviously smart person had prepared a little better for his or her interviews. Is there any way we can help future candidates out with some tips?"

And then nobody actually does anything, because we're all afraid of getting stabbed violently by People Who Don't Know X.

I considered giving out a set of tips in which I actually use variable names like X, rather than real subjects, but decided that in the resultant vacuum, everyone would get upset. Otherwise that approach seemed pretty good, as long as I published under a pseudonym.

In the end, people really need the tips, regardless of how many feelings get hurt along the way. So rather than skirt around the issues, I'm going to give you a few mandatory substitutions for X along with a fair amount of general interview-prep information.

Caveats and Disclaimers

This blog is not endorsed by Google. Google doesn't know I'm publishing these tips. It's just between you and me, OK? Don't tell them I prepped you. Just go kick ass on your interviews and we'll be square.

I'm only talking about general software engineering positions, and interviews for those positions.

These tips are actually generic; there's nothing specific to Google vs. any other software company. I could have been writing these tips about my first software job 20 years ago. That implies that these tips are also timeless, at least for the span of our careers.

These tips obviously won't get you a job on their own. My hope is that by following them you will perform your very best during the interviews.

Oh, and um, why Google?

Oho! Why Google, you ask? Well let's just have that dialog right up front, shall we?

You: Should I work at Google? Is it all they say it is, and more? Will I be serenely happy there? Should I apply immediately?

Me: Yes.

You: To which ques... wait, what do you mean by "Yes?" I didn't even say who I am!

Me: Dude, the answer is Yes. (You may be a woman, but I'm still calling you Dude.)

You: But... but... I am paralyzed by inertia! And I feel a certain comfort level at my current company, or at least I have become relatively inured to the discomfort. I know people here and nobody at Google! I would have to learn Google's build system and technology and stuff! I have no credibility, no reputation there – I would have to start over virtually from scratch! I waited too long, there's no upside! I'm afraaaaaaid!

Me: DUDE. The answer is Yes already, OK? It's an invariant. Everyone else who came to Google was in the exact same position as you are, modulo a handful of famous people with beards that put Gandalf's to shame, but they're a very tiny minority. Everyone who applied had the same reasons for not applying as you do. And everyone here says: "GOSH, I SURE AM HAPPY I CAME HERE!" So just apply already. But prep first.

You: But what if I get a mistrial? I might be smart and qualified, but for some random reason I may do poorly in the interviews and not get an offer! That would be a huge blow to my ego! I would rather pass up the opportunity altogether than have a chance of failure!

Me: Yeah, that's at least partly true. Heck, I kinda didn't make it in on my first attempt, but I begged like a street dog until they gave me a second round of interviews. I caught them in a weak moment. And the second time around, I prepared, and did much better.

The thing is, Google has a well-known false negative rate, which means we sometimes turn away qualified people, because that's considered better than sometimes hiring unqualified people. This is actually an industry-wide thing, but the dial gets turned differently at different companies. At Google the false-negative rate is pretty high. I don't know what it is, but I do know a lot of smart, qualified people who've not made it through our interviews. It's a bummer.

But the really important takeaway is this: if you don't get an offer, you may still be qualified to work here. So it needn't be a blow to your ego at all!

As far as anyone I know can tell, false negatives are completely random, and are unrelated to your skills or qualifications. They can happen from a variety of factors, including but not limited to:

  1. you're having an off day
  2. one or more of your interviewers is having an off day
  3. there were communication issues invisible to you and/or one or more of the interviewers
  4. you got unlucky and got an Interview Anti-Loop
Oh no, not the Interview Anti-Loop!

Yes, I'm afraid you have to worry about this.

What is it, you ask? Well, back when I was at Amazon, we did (and they undoubtedly still do) a LOT of soul-searching about this exact problem. We eventually concluded that every single employee E at Amazon has at least one "Interview Anti-Loop": a set of other employees S who would not hire E. The root cause is important for you to understand when you're going into interviews, so I'll tell you a little about what I've found over the years.

First, you can't tell interviewers what's important. Not at any company. Not unless they're specifically asking you for advice. You have a very narrow window of perhaps one year after an engineer graduates from college to inculcate them in the art of interviewing, after which the window closes and they believe they are a "good interviewer" and they don't need to change their questions, their question styles, their interviewing style, or their feedback style, ever again.

It's a problem. But I've had my hand bitten enough times that I just don't try anymore.

Second problem: every "experienced" interviewer has a set of pet subjects and possibly specific questions that he or she feels is an accurate gauge of a candidate's abilities. The question sets for any two interviewers can be widely different and even entirely non-overlapping.

A classic example found everywhere is: Interviewer A always asks about C++ trivia, filesystems, network protocols and discrete math. Interviewer B always asks about Java trivia, design patterns, unit testing, web frameworks, and software project management. For any given candidate with both A and B on the interview loop, A and B are likely to give very different votes. A and B would probably not even hire each other, given a chance, but they both happened to go through interviewer C, who asked them both about data structures, unix utilities, and processes versus threads, and A and B both happened to squeak by.

That's almost always what happens when you get an offer from a tech company. You just happened to squeak by. Because of the inherently flawed nature of the interviewing process, it's highly likely that someone on the loop will be unimpressed with you, even if you are Alan Turing. Especially if you're Alan Turing, in fact, since it means you obviously don't know C++.

The bottom line is, if you go to an interview at any software company, you should plan for the contingency that you might get genuinely unlucky, and wind up with one or more people from your Interview Anti-Loop on your interview loop. If this happens, you will struggle, then be told that you were not a fit at this time, and then you will feel bad. Just as long as you don't feel meta-bad, everything is OK. You should feel good that you feel bad after this happens, because hey, it means you're human.

And then you should wait 6-12 months and re-apply. That's pretty much the best solution we (or anyone else I know of) could come up with for the false-negative problem. We wipe the slate clean and start over again. There are lots of people here who got in on their second or third attempt, and they're kicking butt.

You can too.

OK, I feel better about potentially not getting hired

Good! So let's get on to those tips, then.

If you've been following along very closely, you'll have realized that I'm interviewer D. Meaning that my personal set of pet questions and topics is just my own, and it's no better or worse than anyone else's. So I can't tell you what it is, no matter how much I'd like to, because I'll offend interviewers A through X who have slightly different working sets.

Instead, I want to prep you for some general topics that I believe are shared by the majority of tech interviewers at Google-like companies. Roughly speaking, this means the company builds a lot of their own software and does a lot of distributed computing. There are other tech-company footprints, the opposite end of the spectrum being companies that outsource everything to consultants and try to use as much third-party software as possible. My tips will be useful only to the extent that the company resembles Google.

So you might as well make it Google, eh?

First, let's talk about non-technical prep.

The Warm-Up

Nobody goes into a boxing match cold. Lesson: you should bring your boxing gloves to the interview. No, wait, sorry, I mean: warm up beforehand!

How do you warm up? Basically there is short-term and long-term warming up, and you should do both.

Long-term warming up means: study and practice for a week or two before the interview. You want your mind to be in the general "mode" of problem solving on whiteboards. If you can do it on a whiteboard, every other medium (laptop, shared network document, whatever) is a cakewalk. So plan for the whiteboard.

Short-term warming up means: get lots of rest the night before, and then do intense, fast-paced warm-ups the morning of the interview.

The two best long-term warm-ups I know of are:

1) Study a data-structures and algorithms book. Why? Because it is the most likely to help you beef up on problem identification. Many interviewers are happy when you understand the broad class of question they're asking without explanation. For instance, if they ask you about coloring U.S. states in different colors, you get major bonus points if you recognize it as a graph-coloring problem, even if you don't actually remember exactly how graph-coloring works.

And if you do remember how it works, then you can probably whip through the answer pretty quickly. So your best bet, interview-prep wise, is to practice the art of recognizing that certain problem classes are best solved with certain algorithms and data structures.

My absolute favorite for this kind of interview preparation is Steven Skiena's The Algorithm Design Manual. More than any other book it helped me understand just how astonishingly commonplace (and important) graph problems are – they should be part of every working programmer's toolkit. The book also covers basic data structures and sorting algorithms, which is a nice bonus. But the gold mine is the second half of the book, which is a sort of encyclopedia of 1-pagers on zillions of useful problems and various ways to solve them, without too much detail. Almost every 1-pager has a simple picture, making it easy to remember. This is a great way to learn how to identify hundreds of problem types.

Other interviewers I know recommend Introduction to Algorithms. It's a true classic and an invaluable resource, but it will probably take you more than 2 weeks to get through it. But if you want to come into your interviews prepped, then consider deferring your application until you've made your way through that book.

2) Have a friend interview you. The friend should ask you a random interview question, and you should go write it on the board. You should keep going until it is complete, no matter how tired or lazy you feel. Do this as much as you can possibly tolerate.

I didn't do these two types of preparation before my first Google interview, and I was absolutely shocked at how bad at whiteboard coding I had become since I had last interviewed seven years prior. It's hard! And I also had forgotten a bunch of algorithms and data structures that I used to know, or at least had heard of.

Going through these exercises for a week prepped me mightily for my second round of Google interviews, and I did way, way better. It made all the difference.

As for short-term preparation, all you can really do is make sure you are as alert and warmed up as possible. Don't go in cold. Solve a few problems and read through your study books. Drink some coffee: it actually helps you think faster, believe it or not. Make sure you spend at least an hour practicing immediately before you walk into the interview. Treat it like a sports game or a music recital, or heck, an exam: if you go in warmed up you'll give your best performance.

Mental Prep

So! You're a hotshot programmer with a long list of accomplishments. Time to forget about all that and focus on interview survival.

You should go in humble, open-minded, and focused.

If you come across as arrogant, then people will question whether they want to work with you. The best way to appear arrogant is to question the validity of the interviewer's question – it really ticks them off, as I pointed out earlier on. Remember how I said you can't tell an interviewer how to interview? Well, that's especially true if you're a candidate.

So don't ask: "gosh, are algorithms really all that important? do you ever need to do that kind of thing in real life? I've never had to do that kind of stuff." You'll just get rejected, so don't say that kind of thing. Treat every question as legitimate, even if you are frustrated that you don't know the answer.

Feel free to ask for help or hints if you're stuck. Some interviewers take points off for that, but occasionally it will get you past some hurdle and give you a good performance on what would have otherwise been a horrible stony half-hour silence.

Don't say "choo choo choo" when you're "thinking".

Don't try to change the subject and answer a different question. Don't try to divert the interviewer from asking you a question by telling war stories. Don't try to bluff your interviewer. You should focus on each problem they're giving you and make your best effort to answer it fully.

Some interviewers will not ask you to write code, but they will expect you to start writing code on the whiteboard at some point during your answer. They will give you hints but won't necessarily come right out and say: "I want you to write some code on the board now." If in doubt, you should ask them if they would like to see code.

Interviewers have vastly different expectations about code. I personally don't care about syntax (unless you write something that could obviously never work in any programming language, at which point I will dive in and verify that you are not, in fact, a circus clown and that it was an honest mistake). But some interviewers are really picky about syntax, and some will even silently mark you down for missing a semicolon or a curly brace, without telling you. I think of these interviewers as – well, it's a technical term that rhymes with "bass soles", but they think of themselves as brilliant technical evaluators, and there's no way to tell them otherwise.

So ask. Ask if they care about syntax, and if they do, try to get it right. Look over your code carefully from different angles and distances. Pretend it's someone else's code and you're tasked with finding bugs in it. You'd be amazed at what you can miss when you're standing 2 feet from a whiteboard with an interviewer staring at your shoulder blades.

It's OK (and highly encouraged) to ask a few clarifying questions, and occasionally verify with the interviewer that you're on the track they want you to be on. Some interviewers will mark you down if you just jump up and start coding, even if you get the code right. They'll say you didn't think carefully first, and you're one of those "let's not do any design" type cowboys. So even if you think you know the answer to the problem, ask some questions and talk about the approach you'll take a little before diving in.

On the flip side, don't take too long before actually solving the problem, or some interviewers will give you a delay-of-game penalty. Try to move (and write) quickly, since often interviewers want to get through more than one question during the interview, and if you solve the first one too slowly then they'll be out of time. They'll mark you down because they couldn't get a full picture of your skills. The benefit of the doubt is rarely given in interviewing.

One last non-technical tip: bring your own whiteboard dry-erase markers. They sell pencil-thin ones at office supply stores, whereas most companies (including Google) tend to stock the fat kind. The thin ones turn your whiteboard from a 480i standard-definition tube into a 58-inch 1080p HD plasma screen. You need all the help you can get, and free whiteboard space is a real blessing.

You should also practice whiteboard space-management skills, such as not starting on the right and coding down into the lower-right corner in Teeny Unreadable Font. Your interviewer will not be impressed. Amusingly, although it always irks me when people do this, I did it during my interviews, too. Just be aware of it!

Oh, and don't let the marker dry out while you're standing there waving it. I'm tellin' ya: you want minimal distractions during the interview, and that one is surprisingly common.

OK, that should be good for non-tech tips. On to X, for some value of X! Don't stab me!

Tech Prep Tips

The best tip is: go get a computer science degree. The more computer science you have, the better. You don't have to have a CS degree, but it helps. It doesn't have to be an advanced degree, but that helps too.

However, you're probably thinking of applying to Google a little sooner than 2 to 8 years from now, so here are some shorter-term tips for you.

Algorithm Complexity: you need to know Big-O. It's a must. If you struggle with basic big-O complexity analysis, then you are almost guaranteed not to get hired. It's, like, one chapter in the beginning of one theory of computation book, so just go read it. You can do it.

Sorting: know how to sort. Don't do bubble-sort. You should know the details of at least one n*log(n) sorting algorithm, preferably two (say, quicksort and merge sort). Merge sort can be highly useful in situations where quicksort is impractical, so take a look at it.

For God's sake, don't try sorting a linked list during the interview.

Hashtables: hashtables are arguably the single most important data structure known to mankind. You absolutely have to know how they work. Again, it's like one chapter in one data structures book, so just go read about them. You should be able to implement one using only arrays in your favorite language, in about the space of one interview.

Trees: you should know about trees. I'm tellin' ya: this is basic stuff, and it's embarrassing to bring it up, but some of you out there don't know basic tree construction, traversal and manipulation algorithms. You should be familiar with binary trees, n-ary trees, and trie-trees at the very very least. Trees are probably the best source of practice problems for your long-term warmup exercises.

You should be familiar with at least one flavor of balanced binary tree, whether it's a red/black tree, a splay tree or an AVL tree. You should actually know how it's implemented.

You should know about tree traversal algorithms: BFS and DFS, and know the difference between inorder, postorder and preorder.

You might not use trees much day-to-day, but if so, it's because you're avoiding tree problems. You won't need to do that anymore once you know how they work. Study up!

Graphs

Graphs are, like, really really important. More than you think. Even if you already think they're important, it's probably more than you think.

There are three basic ways to represent a graph in memory (objects and pointers, matrix, and adjacency list), and you should familiarize yourself with each representation and its pros and cons.

You should know the basic graph traversal algorithms: breadth-first search and depth-first search. You should know their computational complexity, their tradeoffs, and how to implement them in real code.

You should try to study up on fancier algorithms, such as Dijkstra and A*, if you get a chance. They're really great for just about anything, from game programming to distributed computing to you name it. You should know them.

Whenever someone gives you a problem, think graphs. They are the most fundamental and flexible way of representing any kind of a relationship, so it's about a 50-50 shot that any interesting design problem has a graph involved in it. Make absolutely sure you can't think of a way to solve it using graphs before moving on to other solution types. This tip is important!

Other data structures

You should study up on as many other data structures and algorithms as you can fit in that big noggin of yours. You should especially know about the most famous classes of NP-complete problems, such as traveling salesman and the knapsack problem, and be able to recognize them when an interviewer asks you them in disguise.

You should find out what NP-complete means.

Basically, hit that data structures book hard, and try to retain as much of it as you can, and you can't go wrong.

Math

Some interviewers ask basic discrete math questions. This is more prevalent at Google than at other places I've been, and I consider it a Good Thing, even though I'm not particularly good at discrete math. We're surrounded by counting problems, probability problems, and other Discrete Math 101 situations, and those innumerate among us blithely hack around them without knowing what we're doing.

Don't get mad if the interviewer asks math questions. Do your best. Your best will be a heck of a lot better if you spend some time before the interview refreshing your memory on (or teaching yourself) the essentials of combinatorics and probability. You should be familiar with n-choose-k problems and their ilk – the more the better.

I know, I know, you're short on time. But this tip can really help make the difference between a "we're not sure" and a "let's hire her". And it's actually not all that bad – discrete math doesn't use much of the high-school math you studied and forgot. It starts back with elementary-school math and builds up from there, so you can probably pick up what you need for interviews in a couple of days of intense study.

Sadly, I don't have a good recommendation for a Discrete Math book, so if you do, please mention it in the comments. Thanks.

Operating Systems

This is just a plug, from me, for you to know about processes, threads and concurrency issues. A lot of interviewers ask about that stuff, and it's pretty fundamental, so you should know it. Know about locks and mutexes and semaphores and monitors and how they work. Know about deadlock and livelock and how to avoid them. Know what resources a processes needs, and a thread needs, and how context switching works, and how it's initiated by the operating system and underlying hardware. Know a little about scheduling. The world is rapidly moving towards multi-core, and you'll be a dinosaur in a real hurry if you don't understand the fundamentals of "modern" (which is to say, "kinda broken") concurrency constructs.

The best, most practical book I've ever personally read on the subject is Doug Lea's Concurrent Programming in Java. It got me the most bang per page. There are obviously lots of other books on concurrency. I'd avoid the academic ones and focus on the practical stuff, since it's most likely to get asked in interviews.

Coding

You should know at least one programming language really well, and it should preferably be C++ or Java. C# is OK too, since it's pretty similar to Java. You will be expected to write some code in at least some of your interviews. You will be expected to know a fair amount of detail about your favorite programming language.

Other Stuff

Because of the rules I outlined above, it's still possible that you'll get Interviewer A, and none of the stuff you've studied from these tips will be directly useful (except being warmed up.) If so, just do your best. Worst case, you can always come back in 6-12 months, right? Might seem like a long time, but I assure you it will go by in a flash.

The stuff I've covered is actually mostly red-flags: stuff that really worries people if you don't know it. The discrete math is potentially optional, but somewhat risky if you don't know the first thing about it. Everything else I've mentioned you should know cold, and then you'll at least be prepped for the baseline interview level. It could be a lot harder than that, depending on the interviewer, or it could be easy.

It just depends on how lucky you are. Are you feeling lucky? Then give it a try!

Send me your resume

I'll probably batch up any resume submissions people send me and submit them weekly. In the meantime, study up! You have a lot of warming up to do. Real-world work makes you rusty.

I hope this was helpful. Let the flames begin, etc. Yawn.

Portrait of a N00b

 The older I grow, the less important the comma becomes. Let the reader catch his own breath.
— Elizabeth Clarkson Zwart

This is how I used to comment my code, twenty years ago (Note: dramatization):
  /**
* By the time we get to this point in the function,
* our structure is set up properly and we've created
* a buffer large enough to handle the input plus some
* overflow space. I'm not sure if the overflow space
* is strictly necessary, but it can't hurt. Next we
* have to update the counter to account for the fact
* that the caller has read a value without consuming
* it. I considered putting the counter-increment on
* the shoulders of the caller, but since it meant every
* caller had to do it, I figured it made more sense to
* just move it here. We can revisit the decision down
* the road if we find some callers that need the option
* of incrementing it themselves.
*/

counter++; // increment the consumed-value counter


/**
* Now we've got to start traversing the buffer, but we
* need an extra index to do it; otherwise we'll wind up
* at the end of the function without having any idea
* what the initial value was. I considered calling this
* variable 'ref', since in some sense we're going to be
* treating it as a reference, but eventually I decided
* it makes more sense to use 'pos'; I'm definitely open
* to discussion on it, though.
*/

char* pos = buffer; // start our traversal


/**
* NEXT, we...
*/
Does this style look at all familiar? It should! This is, to put it as impolitely as possible, n00b-style. (Incidentally, if u dont no wat a n00b iz, u r 1.)

This is how junior programmers write code. If you've read Malcom Gladwell's remarkable and eye-opening book The Tipping Point, you'll notice a striking similarity to the real-life 2-year-old Emily he describes in Chapter Three, who tells herself stories after her parents leave her room. Here's a short excerpt from one of her stories:
Tomorrow when we wake up from bed, first me and Daddy and Mommy, you, eat breakfast eat breakfast like we usually do, and then we're going to play and then soon as Daddy comes, Carl's going to come over, and then we're going to play a little while. And then Carl and Emily are both going down to the car with somebody, and we're going to ride to nursery school [whispered], and then when we get there, we're all going to get out of the car...
Gladwell's account of Emily is fascinating, as she's allegedly a completely normal 2-year-old; they all do this when Mommy and Daddy aren't around.

Gladwell explains:
Sometimes these stories were what linguists call temporal narratives. She would create a story to try to integrate events, actions, and feelings into one structure — a process that is a critical part of a child's mental development.
If you look back at the comments in my hypothetical code from 20 years ago, you'll see that I was doing exactly what Emily does: making up a temporal narrative in an attempt to carve out a mental picture of the computation for myself. These stories I told myself were a critical part of my mental development as a programmer. I was a child trying to make sense of a big, scary new world.

Most programmers go through this phase. It's perfectly normal.

In contrast, here's what my code tends to look like today:
(defun js2-parse-variables (in-for decl-type)
"Parse a 'var', 'const' or 'let' statement or for-loop initializer.
IN-FOR is true if we are currently in the midst of the init clause of a for.
DECL-TYPE is a token value: either VAR, CONST, or LET depending on context.
Returns the parsed statement node."

(let ((result (make-js2-var-decl-node))
destructuring-init
destructuring
s start tt init name node
(continue t))
;; Examples:
;; var foo = {a: 1, b: 2}, bar = [3, 4];
;; var {b: s2, a: s1} = foo, x = 6, y, [s3, s4] = bar;
(while continue
(setq destructuring nil
s nil
tt (js2-peek-token)
start js2-token-start
init nil)
(if (or (= tt js2-LB) (= tt js2-LC))
;; Destructuring assignment, e.g., var [a, b] = ...
(setq destructuring (js2-parse-primary-expr))
;; Simple variable name
(js2-must-match js2-NAME "msg.bad.var")
(setq name (make-js2-name-node))
(js2-define-symbol decl-type js2-ts-string))
(when (js2-match-token js2-ASSIGN)
(setq init (js2-parse-assign-expr in-for)))
(if destructuring
(progn
(if (null init)
;; for (var [k, v] in foo) is initialized differently
(unless in-for
(js2-report-error "msg.destruct.assign.no.init")))
(setq node (make-js2-destructuring-init-node :start start
:end js2-ts-cursor
:lhs destructuring
:initializer init))
(js2-node-add-children node destructuring init))
;; simple variable, possibly with initializer
(setq node (make-js2-var-init-node :start start
:end js2-ts-cursor
:name name
:initializer init))
(js2-node-add-children node name init))
(js2-block-node-push result node)
(js2-node-add-children result node)
(unless (js2-match-token js2-COMMA)
(setq continue nil)))
result))
If I'd seen this code 20 years ago I'd have been appalled. The lines of code are all crammed together! Some of them aren't even commented! If I'd been given the task of maintaining this code, I'd have been screaming "rewrite!"

I probably write more Java and JavaScript these days, but I picked an Emacs-Lisp function I wrote recently to highlight how alien my code today would have looked to me twenty years ago.

To be fair, this function is actually a port of some Java code from Mozilla Rhino's JavaScript parser, which in turn is a port of some C code from SpiderMonkey's parser, which in turn was probably borrowed and modified from some other compiler. Compiler code tends to have some of the purest lineage around, tracing back to the assembly-language code they wrote for the first compilers 40 or 50 years ago. Which means it's going to be a bit on the ugly side compared to "ordinary" code.

But when I write code in other languages these days, even in Java, it looks a lot more like this Emacs Lisp fragment than like the n00b code I was writing 20 years ago. It's denser: there's less whitespace and far less commenting. Most of the commenting is in the form of doc-comments for automated API-doc extraction. On the whole, my code today is much more compressed.

In the old days, seeing too much code at once quite frankly exceeded my complexity threshold, and when I had to work with it I'd typically try to rewrite it or at least comment it heavily. Today, however, I just slog through it without complaining (much). When I have a specific goal in mind and a complicated piece of code to write, I spend my time making it happen rather than telling myself stories about it.

A decade of experience makes you a teenager

After going through their 2-year-old phase, programmers eventually have to go through a stupid-teenager phase. All this month I've been hearing sad but unsurprising news stories about teenagers getting stuck on big rocks, being killed falling off cliffs, or dying of exposure. I'm actually lucky the same didn't happen to me when I was a teenager. It's just a bad time for us. Even though teenagers are old enough to understand the warnings, they have this feeling of invincibility that gets them into trouble and often mortal peril.

The programming equivalent happens around us all the time too. Junior programmers with five to ten years of experience under their belts (still n00bs in their own way) attempt to build giant systems and eventually find themselves stuck on the cliff waiting for a helicopter bailout, telling themselves "my next system rewrite will be better!" Or they fall off the cliff – i.e., the project gets canceled, people get laid off, maybe the company goes under.

Yes, I've gone through that phase too. And let's face it: even seasoned programmers need a little optimism and a little bravery in order tackle real challenges. Even as an experienced programmer, you should expect to fail at projects occasionally or you're probably not trying hard enough. Once again, this is all perfectly normal.

That being said, as a hiring manager or company owner you should keep in mind that "5 to 10 years of experience" on a resume does not translate to "experienced"; it means "crazy invincible-feeling teenager with a 50/50 shot at writing a pile of crap that he or she and his or her team can't handle, and they'll eventually, possibly repeatedly, try to rewrite it all." It's just how things are: programmers can't escape being teenagers at some point.

Building compression tolerance

Hopefully the scene I've painted so far helps you understand why sometimes you look at code and you just hate it immediately. If you're a n00b, you'll look at experienced code and say it's impenetrable, undisciplined crap written by someone who never learned the essentials of modern software engineering. If you're a veteran, you'll look at n00b code and say it's over-commented, ornamental fluff that an intern could have written in a single night of heavy drinking.

The sticking point is compression-tolerance. As you write code through your career, especially if it's code spanning very different languages and problem domains, your tolerance for code compression increases. It's no different from the progression from reading children's books with giant text to increasingly complex novels with smaller text and bigger words. (This progression eventually leads to Finnegan's Wake, if you're curious.)

The question is, what do you do when the two groups (vets and n00bs) need to share code?

I've heard (and even made) the argument that you should write for the lowest common denominator of programmers. If you write code that newer programmers can't understand, then you're hurting everyone's productivity and chances for success, or so the argument goes.

However, I can now finally also see things from the veteran point of view. A programmer with a high tolerance for compression is actually hindered by a screenful of storytelling. Why? Because in order to understand a code base you need to be able to pack as much of it as possible into your head. If it's a complicated algorithm, a veteran programmer wants to see the whole thing on the screen, which means reducing the number of blank lines and inline comments – especially comments that simply reiterate what the code is doing. This is exactly the opposite of what a n00b programmer wants. n00bs want to focus on one statement or expression at a time, moving all the code around it out of view so they can concentrate, fer cryin' out loud.

So it's a problem.

Should a team write for the least common denominator? And if so, exactly how compressed should they make the code? I think the question may be unanswerable. It's like asking for a single format for all books, from children's books to epic novels. Each team is going to have its own average preference. I suspect it's a good idea to encourage people to move their stories into design documents and leave them out of the code, since a junior programmer forced to work in a compressed code base may well grow up faster.

As for me, at this point in my career I would rather puzzle through a small, dense, complex piece of code than a massive system with thousands of files containing mostly comments and whitespace. To some people this trait undoubtedly flags me as a cranky old dinosaur. Since this is likely the majority of programmers out there, maybe I am a cranky old dinosaur. Rawr.

Metadata Madness

Everyone knows that comments are metadata: information about the data (in this case, the data being your source code.) But people often forget that comments aren't just a kind of metadata. Comments and metadata are the same thing!

Metadata is any kind of description or model of something else. The comments in your code are just a a natural-language description of the computation. What makes metadata meta-data is that it's not strictly necessary. If I have a dog with some pedigree paperwork, and I lose the paperwork, I still have a perfectly valid dog.

You already know the comments you write have no bearing on the runtime operation of your code. The compiler just throws them away. And we've established that one hallmark of a n00b programmer is commenting to excess: in a sense, modeling every single step of the computation in painstaking detail, just like Emily modeled her ideal Friday by walking through every step and reassuring her 2-year-old self that she really did understand how it was going to work.

Well, we also know that static types are just metadata. They're a specialized kind of comment targeted at two kinds of readers: programmers and compilers. Static types tell a story about the computation, presumably to help both reader groups understand the intent of the program. But the static types can be thrown away at runtime, because in the end they're just stylized comments. They're like pedigree paperwork: it might make a certain insecure personality type happier about their dog, but the dog certainly doesn't care.

If static types are comments, then I think we can conclude that people who rely too much on static types, people who really love the static modeling process, are n00bs.

Hee hee.

Seriously, though: I'm not actually bashing on static-typing here; I'm bashing on the over-application of it. Junior programmers overuse static typing in the exact same way, and for the same reasons, as they overuse comments.

I'll elaborate by first drawing a parallel to data modeling, which is another kind of "static typing". If you've been working in a field that uses relational databases heavily, you'll probably have noticed that there's a certain personality type that's drawn to relational data modeling as a career unto itself. They're usually the logical modelers, not the physical modelers. They may have begun their careers as programmers, but they find they really love data modeling; it's like a calling for them.

If you know the kind of person I'm talking about, you'll doubtless also have noticed they're always getting in your way. They band together and form Database Cabals and Schema Councils and other obstructive bureacracies in the name of safety. And they spend a lot of time fighting with the engineers trying to get stuff done, especially at the fringes: teams that are not working directly with the schema associated with the main revenue stream for the company, but are out trying to solve tangential problems and just happen, by misfortune, to be homed in the same databases.

I've been in surprisingly many situations at different companies where I had a fringe team that was being held up by data modelers who were overly-concerned about data integrity when the real business need was flexibility, which is sort of the opposite of strong data modeling. When you need flexible storage, name/value pairs can get you a long, long, LONG way. (I have a whole blog planned on this topic, in fact. It's one of my favorite vapor-blogs at the moment.)

It's obviously important to do some amount of data modeling. What's not so obvious is when to stop. It's like commenting your code: newer programmers just don't know when to quit. When you're a little insecure, adding comments and metadata are a great security-blanket that make you feel busy when you've in fact stopped making forward progress and are just reiterating (or perhaps teaching yourself) what's already been accomplished.

Hardcore logical data modelers often suffer from an affliction called metadata addiction. Metadata modeling is seductive. It lets you take things at a leisurely pace. You don't have to be faced with too much complexity at once, because everything has to go in a new box before you'll look at it. To be sure, having some metadata (be it a data model, or static types, or comments) is important for human communication and to some extent for performance tuning. But a surprising percentage of people in our industry take it too far, and make describing an activity more important than the activity itself.

The metadata-addiction phenomenon applies equally to coders. Code is data, and data is code. The two are inextricably linked. The data in your genes is code. The floor plans for your house are code. The two concepts are actually indistinguishable, linked at a fundamental level by the idea of an Interpreter, which sits at the very heart of Computer Science. Metadata, on the other hand, is more like the kidney of Computer Science. In practice you can lose half of it and hardly notice.

Creeping bureacracy

I think that by far the biggest reason that C++ and Java are the predominant industry languages today, as opposed to dynamic languages like Perl/Python/Ruby or academic languages like Modula-3/SML/Haskell, is that C++ and Java cater to both secure and insecure programmers.

You can write C++ like straight C code if you like, using buffers and pointers and nary a user-defined type to be found. Or you can spend weeks agonizing over template metaprogramming with your peers, trying to force the type system to do something it's just not powerful enough to express. Guess which group gets more actual work done? My bet would be the C coders. C++ helps them iron things out in sticky situations (e.g. data structures) where you need a little more structure around the public API, but for the most part they're just moving data around and running algorithms, rather than trying to coerce their error-handling system to catch programmatic errors. It's fun to try to make a bulletproof model, but their peers are making them look bad by actually deploying systems. In practice, trying to make an error-proof system is way more work than it's worth.

Similarly, you can write Java code more or less like straight C, and a lot of seasoned programmers do. It's a little nicer than C because it has object-orientation built in, but that's fairly orthogonal to the static type system. You don't need static types for OOP: in fact OOP was born and proven in dynamic languages like Smalltalk and Lisp long before it was picked up by the static-type camps. The important elements of OOP are syntax (and even that's optional) and an object model implemented in the runtime.

So you can write Java code that's object-oriented but C-like using arrays, vectors, linked lists, hashtables, and a minimal sprinkling of classes. Or you can spend years creating mountains of class hierarchies and volumes of UML in a heroic effort to tell people stories about all the great code you're going to write someday.

Perl, Python and Ruby fail to attract many Java and C++ programmers because, well, they force you to get stuff done. It's not very easy to drag your heels and dicker with class modeling in dynamic languages, although I suppose some people still manage. By and large these languages (like C) force you to face the computation head-on. That makes them really unpopular with metadata-addicted n00bs. It's funny, but I used to get really pissed off at Larry Wall for calling Java programmers "babies". It turns out the situation is a little more complicated than that... but only a little.

And Haskell, OCaml and their ilk are part of a 45-year-old static-typing movement within academia to try to force people to model everything. Programmers hate that. These languages will never, ever enjoy any substantial commercial success, for the exact same reason the Semantic Web is a failure. You can't force people to provide metadata for everything they do. They'll hate you.

One very real technical problem with the forced-modeling approaches that static type systems are often "wrong". It may be hard to imagine, because by a certain definition they can't be "wrong": the code (or data) is programmatically checked to conform to whatever constraints are imposed by the type system. So the code or data always matches the type model. But the type system is "wrong" whenever it cannot match the intended computational model. Every time want to use multiple inheritance or mixins in Java's type system, Java is "wrong", because it can't do what you want. You have to take the most natural design and corrupt it to fit Java's view of the world.

An important theoretical idea behind type systems is "soundness". Researchers love to go on about whether a type system is "sound" or not, and "unsound" type systems are considered bad. C++ and Java have "unsound" type systems. What researchers fail to realize is that until they can come up with a type system that is never "wrong" in the sense I described earlier, they will continue to frustrate their users, and their languages will be abandoned for more flexible ones. (And, Scala folks, it can't just be possible to express things like property lists – it has to be trivial.)

To date, the more "sound" a type system is, the more often it's wrong when you try to use it. This is half the reason that C++ and Java are so successful: they let you stop using the type system whenever it gets in your way.

The other half of their success stems from the ability to create user-defined static types. Not, mind you, because they're helpful in creating solidly-engineered systems. They are, sure. But the reason C++ and Java (particularly Java) have been so successful is that their type systems form a "let's not get any work done" playground for n00bs to spend time modeling things and telling themselves stories.

Java has been overrun by metadata-addicted n00bs. You can't go to a bookstore or visit a forum or (at some companies) even go to the bathroom without hearing from them. You can't actually model everything; it's formally impossible and pragmatically a dead-end. But they try. And they tell their peers (just like our metadata-addicted logical data modelers) that you have to model everything or you're a Bad Citizen.

This gets them stuck on cliffs again and again, and because they're teenagers they don't understand what they did wrong. Static type models have weight and inertia. They take time to create, time to maintain, time to change, and time to work around when they're wrong. They're just comments, nothing more. All metadata is equivalent in the sense of being tangential documentation. And static type models get directly in the way of flexibility, rapid development, and system-extensibility.

I've deleted several thousand words about the evolution of Apache Struts and WebWork, an example framework I chose to illustrate my point. Rather than waste a bunch of time with it, I'll just give you a quote from one of the Struts developers in "The Evolution of Struts 2":
...the Struts 1 code base didn�t lend itself to drastic improvements, and its feature set was rather limited, particularly lacking in features such as Ajax, rapid development, and extensibility."
Struts 2 was thrown away for WebWork, which was in the process of throwing away version 1 (for similar reasons) in favor of version 2 (which has all the same problems).

Some of those several thousand words were devoted to JUnit 4, which has comically (almost tragically) locked on, n00b-style, to the idea that Java 5 annotations, being another form of metadata, are the answer to mankind's centuries of struggle. They've moved all their code out of the method bodies and into the annotations sections. It's truly the most absurd overuse of metadata I've ever seen. But there isn't space to cover it here; I encourage you to go goggle at it.

There are die-hard Java folks out there who are practically gasping to inject the opinion, right here, that "rapid development" is a byproduct of static typing, via IDEs that can traverse the model.

Why, then, was Struts considered by its own developers to be a failure of rapid development? The answer, my dear die-hard Java fans, is that a sufficiently large model can outweigh its own benefits. Even an IDE can't make things go faster when you have ten thousand classes in your system. Development slows because you're being buried in metadata! Sure, the IDE can help you navigate around it, but once you've created an ocean, even the best boats in the world take a long time to move around it.

There are hundreds of open-source and proprietary Java frameworks out there that were designed by code-teenagers and are in perpetual trouble. I've often complained that the problem is Java, and while I think the Java language (which I've come to realize is disturbingly Pascal-like) is partly to blame, I think the bigger problem is cultural: it's hard to restrain metadata addiction once it begins creeping into a project, a team, or an organization.

Java programmers, and logical data modelers, and other metadata-addicted developers, are burying us with their "comments" in the form of models within their static type system. Just like I did when I was a n00b. But they're doing it with the best of intentions, and they're young and eager and energetic, and they stand on street corners and hand you leaflets about how great it is to model everything.

Seasoned programmers ignore them and just get it done.

Solutions and takeaways

Software engineering is hard to get right. One person's pretty data model looks like metadata-addiction to another person.

I think we can learn some lessons from code-commenting: don't try to model everything! You need to step back and let the code speak for itself.

For instance, as just one random illustrative example, you might need to return 2 values from a function in Java (a language with no direct support for multiple return values). Should you model it as a MyFunctionCallResult class with named ValueOne and ValueTwo fields (presumably with actual names appropriate to the problem at hand)? Or should you just return a 2-element array (possibly of mixed types) and have the caller unpack it?

I think the general answer to this is: when in doubt, don't model it. Just get the code written, make forward progress. Don't let yourself get bogged down with the details of modeling a helper class that you're creating for documentation purposes.

If it's a public-facing API, take a lesson from doc-comments (which should be present even in seasoned code), and do model it. Just don't go overboard with it. Your users don't want to see page after page of diagrams just to make a call to your service.

Lastly, if you're revisiting your code down the road and you find a spot that's always confusing you, or isn't performing well, consider adding some extra static types to clarify it (for you and for your compiler). Just keep in mind that it's a trade-off: you're introducing clarifying metadata at the cost of maintenance, upkeep, flexibility, testability and extensibility. Don't go too wild with it.

That way the cliff you build will stay small enough for you to climb down without a helicopter rescue.

Postscript

I'm leaving comments on, at least until "click-my-link" spam starts to surface. I'm curious to know how this entry goes over. This was an especially difficult entry to write. I did a lot of editing on it, and left out a lot as a result. I feel like I may not have made my points as clearly as I'd like. And I'm sure I haven't convinced the metadata-addicted that they have a problem, although at least now they know someone out there thinks they have a problem, which is a start.

Let me know what you think!

 
Internet