How to make any candidate fail a software engineer interview

* Please note this is satire!

So you have a candidate coming in to interview for that open software engineer position on your team but you really have your mind made up for another candidate? What do you do?

Easy! Here’s how you can make any candidate fail!

Show up late to the interview, then make ongoing comments about how little time there is.

“Hi, sorry I’m late. Well there won’t be much time but we have to get through all my questions anyway, I guess.” Or, “I know we don’t have much time left but I will need you to design Uber and scale it globally!”

Come ready with some out-of-left-field “softball” questions to start.

You want these questions to sound easy to the hiring committee. But if you take even easy questions out of left field it should catch the candidate off guard. A good class of questions are those around a specific language’s quirks. They can be as simple as, for example, a Java question like, “If I create an interface and add a final method, will it compile?” The answer is no, right? But the candidate may be so used to creating interfaces without putting “final” on the front, that they never thought to try it and have no idea if it will compile or not.

Another question might be, “Given the following code, will it compile?”

interface WontCompile {

  String String();

}

Actually, yes, this will compile! Since it is named “WontCompile” and the method name is a Java keyword, your candidate will be entirely defeated.

Other good questions might be about little-used and very specific language keywords. “What does the volatile keyword in Java do? Give some examples of its use.” Even if the candidate answers a question like this you can later claim that their answer wasn’t very good or that their examples didn’t cover the “classic” well-known examples.

Still, the candidate might know this. So if your language quirks questions fail, try asking questions about random libraries. “Can EasyMock or Mockito mock final classes?” Answer is no but it is totally the kind of question that will throw them off!

Bring a wicked algorithm problem with an overly narrow answer
“Write a Sudoku solver” is a good one. But even simple things like “Implement Timsort” are fine. Who knows how to do that off the top of their head? Good luck and bye bye candidate!

Bring an overly broad design problem.
“Design the infrastructure and software for an Uber competitor that can scale globally.” Design problems are the best because design is subjective and you can claim that they failed no matter what answer they give. A broad design problem is also daunting, and your goal is to play on this candidates nerves. “Design a central elevator control system for a five-skyscraper complex in Manhattan.”

Create a distraction!
Bring food or drink, preferably with a strong smell, and eat or slurp loudly.

If all else fails, have a coworker call you on the cell and take the phone call during the interview! Gets ’em every time!

Well, I hope this is helpful to all of you out there that have to go through the motions of interviews to meet whatever quotas they’re setting over in HR. Until next time . . .

Isolate Change in Microservices

I’m finally seeing the “microservice” trend starting to fade a bit. An excellent article came through my Twitter feed the other day, Sean Kelly’s “Microservices, please don’t.” His stuff is remarkable for how he draws the connection between coding practices in a monolith and their equivalent in a microservices architecture. It seems obvious but I haven’t seen too many people pay attention to it.

A solid SOA approach begins in the code itself and moves out into the physical topology of the stack as time moves on.

One of the issues that should be addressed in SOA is how to avoid shackling services together. A simple change in one of them shouldn’t create a cascading set of changes across multiple services. Likewise code in a monolith should be architected to isolate change and prevent cascading updates across classes or packages.

Domain-Driven Design addresses this issue for the single application and some of its rules apply equally well. For example, don’t pass the same object around inside the application that you pass across externally. There’s always a layer in true DDD applications that takes any DTO from an external source (like a web service or database) and keeps it external to the application by translating it to another object in the language of the domain inside the application. There’s a huge temptation to skip this step but every time I’ve seen it done it creates huge problems at some point.

Likewise in a microservices world, the requests and responses chattering between the services should never be a reverse dependency that force all of the services to change whenever they do, whether the specific service cares about the change or not. There should be a good fencing strategy going on that allows them to change with a minimum of pain. And that’s really no different than all of the classic object-oriented design advice. Keep in mind that Uncle Bob’s definition of “single responsibility” is “one reason to change”–not some of the other common misunderstandings passed around.

Anyway, the bottom line point in this is what software luminaries have always known and said: there’s no architecture, no ceremony or formula that you can follow which will not crumble when divorced from the context of good underlying engineering principles .

scala-logo-small

Proof that it is easier to write bugs in Java than in Scala, at least in for-loops

This SO is extremely informative. The questioner shows two functionally identical blocks of code (or so it seems)–one in Java and one in Scala. Somehow the Java one executes in 6ms. Meanwhile the Scala one takes over 1000ms.

The surprise wears off once you read the first answer. Instead we get a new surprise: the blocks of code were not identical. Instead, the Java code contains a bug. The author had quite accidentally swapped “i” for “j” in a for-loop.

The answerer rightly points out the advantage of Scala for loops: by dispensing with explicit index manipulation and providing direct syntax to express the loop bounds, this whole class of bugs is eliminated. The scala version below is both more clear and less error-prone.

Java (can you spot the bug):

for (int i = 0;i < N;i++) {
        float score = 0.0f;
        for (int j = 0; i < R;i++) { //oops!
            score += u[j] * t[i][j];
        }
        if (score > maxScore) {
            maxScore = score;
        }

    }

Scala:

for ( i <- 0 until N) {
  var score = 0.0f
  for (j <- 0 until R) {
    score += u(j) * t(i)(j)
  }
  if (score > maxScore) {
    maxScore = score
  }

}

I still added yet another comment: it is better not to use i and j as loop indices either way, because the human eye is not very good at distinguishing the two. It would still be very easy here to swap i and j in line 4 and not notice. Changing the names to x and y is probably best.