A pleasant walk through computing

Comment for me? Send an email. I might even update the post!

The Better Software Engineer Interview Process

I've been finding my next job. I've looked at literally hundreds of listings and been on several interviews. Over my career, I've interviewed a lot. Today, software engineer interviews work mostly like this:

  1. Screening interview ("do we want to proceed with you?")
  2. Development Manager interview ("do I want to work with you?")
  3. Technical interview or assessment ("can you do the job?")
  4. Other Management interviews ("do we have any objections?")

There can be as low as three (rarely two) steps. I've literally seen it up to six. A six-step interview!

One intended goal for this process, I think, is to reduce the amount of time taken by management and developers for interviews so they can focus on coding. Another reason--again, my opinion--is there's a belief that management can screen out for fit early.

Fit matters. I care a lot about whether I'll fit in with a prospective employer. But, after quite a few recent interviews and really pondering and reading about hiring, I think the typical process is backward, biased, onerous, and ineffective.

A Better Way

Here are the steps I'd like to see.

  1. Initial, online technical assessment using real-world coding. No FizzBuzz, no "reverse this string the hard way."1
  2. Work with the team.
  3. Development Manager interview.

1. Online Assessment

I've been skeptical of online skill assessments in the past, but a recent experience has warmed me to them. While still not as good as working with one's daily tools such as Visual Studio, the online interface was very good. So, why should companies start with (and pay for!) this assessment?

  • Many candidates will drop out because they know they're not ready. This reduces the pool that the development team needs to assess. It's self-selection.
  • The remaining results will be reasonably apples-to-apples.
  • What matters first is "can you do the job."

The skills assessment can be tailored, so junior devs are assessed differently than seniors and architects. And the goal is to gain information, not punish people for not having arcane knowledge. "The basics" (you know, bubble sorting) really don't apply day-to-day. Let me show you I can write testable, clean, object-oriented code!

A fair, online assessment reduces lots of bias. A candidate shouldn't be disregarded out of the gate just because a hiring manager or the candidate hasn't had lunch yet. This is more common than people want to admit.2

2. Team Work

With the assessment results and resumes in hand, the development team can--with coaching from management and HR--decide who they want to meet. Let me say that again. The developers choose. You can bet they'll be careful with their time. In my view, they should ideally work on some code together, or do something that shows the candidate how life will really be. In a word, collaborate. This shouldn't be a "let's talk" meeting. Pull an item from the backlog, discuss how it might be approached, do some pair programming or even mob programming.3

The candidate will be working mostly with developers. They have the biggest stake, so they should have the biggest say in hiring. This is even more important if you claim to be an Agile shop. If you aren't letting developers self-manage their teams, you may still be a top-down bureaucracy.

3. Management Blessing

Someone's going to chafe at my suggestion that the final step is only with the development manager; that is, the person who will be the candidate's direct supervisor, or at most one level above that. But why have you promoted people to management/leadership positions if you're not going to trust their judgement? By now in the process, the only candidates who talk to the manager have been pre-approved by the development team she'll be working with. There's really no reason to bring in other managers, except to stroke their egos and forestall "why wasn't I consulted?" comments later.

Besides, most managers complain they're too busy with endless meetings. This reduces meetings.

Other managers and execs should certainly introduce themselves after the hiring. But if a qualified developer who is liked by the people she'll be working with doesn't get a job because the CEO or president has a "gut feeling," and needs to "meet everyone who's going to work here," a disservice has been done to the entire organization. It signals that people's careers are at the mercy of caprice.

Change Your Ways, It'll Save You Money and Improve Your Culture

Companies spend a lot of money on recruiters, time spent reviewing resumes, time spent in interviews. But have they really evaluated whether that money is being well-spent? Have they applied research and evidence, or are they interviewing software engineers the same way they always have?

This article proposes the answer is, generally, no. We're hiring developers using a traditional model. And we're getting traditionally chancy results.

I learned decades ago to look for these qualities as part of hiring, and they still apply.

  1. Can the person do the job?
  2. Will the person do the job?
  3. Does the person fit?

The principles I've outlined above boil down to.

  • Reduce initial bias
  • Let developers hire developers (with help)
  • Trust your colleagues

I'm no expert, but I think we can hire better.4

References


  1. FizzBuzz can have value if done as pair-programming, but requires a different skill set on the part of the interviewer.

    As far as the "find substrings in a string" tradition, in my opinion, it's outdated and useless. The technical interviews where a couple of developers assign a seemingly trivial task and watch in silence while the candidate tries to work it out is just terrible. It's completely removed from the reality of the job (I hope!), and puts useless pressure on the candidate.

    It isn't an assessment. It's a hazing.

  2. As discussed by Daniel Kahneman in his book Noise, and reported on in this article.

  3. This was one of my favorite interview experiences.

  4. To be intellectually fair, I really haven't found out what research there's been on effective developer hiring practices. I'm just voicing a slightly educated opinion that may be dead wrong.

Meditation on The Mythical Man-Month: Who Failed on the Tower of Babel Project?

Caveat
I'm not a biblical scholar. This post treads on sensitive ground regarding matters of theology. My intention isn't to critique faith, but instead is the same as Brooks's: interpret the account of the Tower of Babel through the lens of project and corporate management. I hope I've navigated the line between serious and tongue-in-cheek successfully.

In his seminal 1975 book The Mythical Man-Month, author and engineer Frederick P. Brooks starts chapter 7, "Why Did the Tower of Babel Fail?" with the relevant Biblical text.

Now the whole earth used only one language, with few words. On the occasion of a migration from the east, men discovered a plain in the land of Shinar, and settled there. Then they said to one another, "Come, let us make bricks, burning them well." So they used bricks for stone, and bitumen for mortar. Then they said, "Come, let us build ourselves a city with a tower whose top shall reach the heavens (thus making a name for ourselves), so that we may not be scattered all over the earth." Then the Lord came down to look at the city and tower which human beings had built. The Lord said, "They are just one people, and they all have the same language. If this is what they can do as a beginning, then nothing that they resolve to do will be impossible for them. Come, let us go down, and there make such a babble of their language that they will not understand one another's speech." Thus the Lord dispersed them from there all over the earth, so that they had to stop building the city.

GENESIS 11:1-8

As an aside, it's fascinating that after a solid search I don't find this translation anywhere else but in Brooks's book. It seems unlikely he played fast and loose with the Bible, so where did his translation come from?

But to the point. Brooks makes the case that the Tower project failed, and that its failure was due to lack of communication and organization by the development team.

Is this supported by the text?

The first question to answer is whether the project was completed. Initially, reading "Then the Lord came down to look at the city and tower which human beings had built," it seems they did complete the city and tower. The puzzle is in the comment, "If this is what they can do as a beginning," which implies the work is merely started. But if it's merely started, how is there even a tower?

The New International Version translates this subtly--but crucially--differently.

But the LORD came down to see the city and the tower the people were building. [Emphasis mine]

However, many other translations use the past tense, "built."

The answer seems to be in the following statements that the Lord confused the language, scattered the people, and they "had to stop building the city." It appears clear the work was unfinished and the past tense "built" should be read as "built so far" rather than "completed."

Is an uncompleted project a failure? Not necessarily. Sometimes projects are abandoned because priorities change. We need to understand, why wasn't this project completed?

So, let's examine the project as a corporate development effort as Brooks did, but without--in my opinion--his bias.

  • The developers had a clear goal and motivation.
  • They began with great success, communicating very well and accomplishing quality work.
  • The CEO checked up on them and felt threatened by their success.
  • He didn't directly cancel the project. He broke up the teams. Not only that, he created barriers to communication.
  • At that point, the developers gave up on the project.

Let me call the first point out again: the Tower of Babel was not failing. The development team was succeeding. The evidence points to the CEO as being the source of the failure, not the developers.

Before making that case, one question is why did the CEO react that way? Why did he feel threatened? The usual reason given for the Lord's actions is the people's hubris.1 They--from the Lord's viewpoint--are trying to achieve godliness, and the Lord and his host (the C-level execs, if you will) don't take kindly to that. They don't want the people making "a name for themselves." Maybe they see the roots of a competitive company growing within their own organization!

From the people's point of view, their goal is the opposite. They want to stay together, not be broken up, and see their project as the means to accomplish that goal. If making a name for themselves is against company policy, they don't seem to know it.

Brooks's purpose in the chapter is showing that poor communication and organization cause major project problems. I agree, and so I believe does lots of research. Where I disagree with Brooks in his metaphor is who's responsible. This isn't a trivial point; it's a problem I've routinely seen in the dozens of companies I've worked for.

So now we come to the crux: What were the communication and organization problems?

I think there are a few important answers. Framing it in software development terms,

  1. The development department didn't communicate their intentions well enough to the CEO.
  2. The CEO was ignorant of what was going on in the company.
  3. The CEO didn't have a clear mission for the organization.
  4. The CEO valued punishment over learning.

If it seems like I'm laying most of the blame for the failed Tower at executive management's feet, I am. The CEO, in this organization, has developed a reputation for being omniscient. It was reasonable for the development department to believe he knew their plans. After all, they stated them out in the open, and such a big project could hardly be missed even in the planning stages.

Still, they could have made sure. After all, the CEO also has a reputation as a bit of a hot head. Maybe the CIO assumed too much or didn't talk the the CEO directly. A few emails and phone calls might have helped. Something like, "We've settled into our new offices. We're working really well together and want that to continue. We're thinking of showing what we can do by building this beautiful social network application called 'City and Tower.' Is that in line with your goals?"

The fact that they missed the mark on such a major project tells me the CEO didn't establish a clear vision. His development department was literally wandering. They shouldn't have been blamed for making the best of their situation.

What's worse is the CEO's reaction when he finds out about the project. He doesn't ask, "How could I have done better?" In fact, he doesn't confirm or consider their motivation. He assumes bad intent on the team's part. There's no conversation. No communication.

Even worse, he doesn't see the opportunity in the developers' excellent work. He responds in an Industrial Age, J.P. Morgan command-and-coerce style. "I'm the boss, you're threatening my power and position, I demand loyalty, so I'm firing you."

The developers showed the hallmarks of drive: autonomy, mastery, and purpose.2 Their initiative should have been rewarded and redirected. What would have been good advice to the CEO?

  1. Ask yourself: "How did I not know about this project?"
  2. Ask the team: "What's your motivation? How does this project help the organization?"
  3. Reflect: "Did my actions or lack of direction affect their decision?"
  4. Reflect: "I feel threatened. Is the threat real?"
  5. Reflect: "Did they do the wrong thing well? If so, can I harness that in service to the organization?"
  6. Act: "I apologize for my part in not communicating well. Let's improve that. You all started something amazing, but I think it's not in line with our objectives. Let's see if our objectives need to be adjusted, but if not let's bring your team to bear on our shared mission."

I agree the Tower project failed because of poor communication and organization. But the primary failure was at the top management level. What the CEO communicated most successfully was:

  • "I won't be clear in what I want."
  • "I don't know what's going on."
  • "I'll punish you if I think you're against me."
  • "I'm never to blame."

These are characteristic of what Ron Westrum defines as a pathological culture, which is worse than a bureaucratic one.

Pathological Bureaucratic Generative
Power oriented Rule oriented Performance oriented
Low cooperation Modest cooperation High cooperation
Messengers "shot" Messengers neglected Messengers trained
Responsibilities shirked Narrow responsibilities Risks are shared
Bridging discouraged Bridging tolerated Bridging encouraged
Failure leads to scapegoating Failure leads to justice Failure leads to inquiry
Novelty crushed Novelty leads to problems Novelty implemented

While there were mistakes on both sides, the clans of Noah's sons really deserved better, especially after all they'd gone through.

Imagine what wonderful products and services that team could have built in a generative organizational culture!

Resources


  1. I think it's pretty well established the reason for the myth of Babel exists at all is early people were trying to figure out "why do we have multiple languages?" Linguistics wasn't a thing, yet, and understanding the evolution of language is super hard anyway, so it was easier--and reasonable--to basically say "God did it." I just wish they hadn't tacked on "and it's our fault."

  2. From Drive by Daniel Pink, see Resources.

.NET MAUI Progressing From a Default Project Part 6 - Revisiting Unit Testing

The Series

Level: Moderate

This series assumes the developer is familiar with .NET MAUI, the Model-View-ViewModel pattern, and has worked through one or more tutorials such as the excellent James Montemagno's Workshop.

Source: https://github.com/bladewolf55/net-maui-progression

(Someone Else's) Solution to Unit Testing .NET MAUI Projects

In part 2, I discussed how .NET MAUI didn't support unit testing, and that you could separate out the namespaces into their own projects. And that's still true and useful. But for many projects that's overkill. In my opinion, it's especially egregious for unit testing the View Models, which I'd prefer stay with the UI project.

In his video Unit Testing .NET MAUI Apps with xUnit, Gerald Versluis demonstrates how to modify the project to allow direct unit testing. It's pretty simple, I must say, and for fun I'll take the solution from part 5 and collapse it back into a single project.

If you want to just see the answer, scroll down to The Secret Sauce.

Ideally, as long as I keep the namespaces the same, everything should work the same and pass perfectly with very little effort.

Creating the namespace folder structure

Right now, we have separate projects for our domain-driven design.

Let's recreate those namespaces in the Maui.Progression project. Create folders like so.

Now copy the files and folders from the projects into the new folders.

Add this NuGet package to the Maui.Progression project.

  • Microsoft.Toolkit.Mvvm

If we had other dependencies, they'd need to be added as well.

In the 'Maui.Progression.UnitTests' project, add a project reference to Maui.Progression

Now delete these projects:

  • Maui.Progression.Domain
  • Maui.Progression.DomainServices
  • Maui.Progression.ViewModels

Their references will automatically be removed from the unit test project.

You can try to simply rebuild the solution. But I had to close and reopen Visual Studio, then clean/rebuild. The build will fail, which is expected.

The Secret Sauce

As discussed in part 2, the reason I couldn't just unit test the .NET MAUI project is because it needs to include a framework of net6.0. The other reason I didn't know about, that Versluis explains, is if I add the net6.0 framework it needs to build as a DLL, not an Exe. This removes the "Main method required" error.

Here's how to do that.

Edit your Maui.Progression.csproj file, either by selecting it or right-click the project name and choosing "Edit Project File".

Modify the TargetFrameworks line to include net6.0. I put it first.

<TargetFrameworks>net6.0;net6.0-android;net6.0-ios;net6.0-maccatalyst</TargetFrameworks>

Here's the kicker. Modify the OutputType to conditionally generate an Exe for everything except the net6.0 framework. DLL is the default when Exe isn't selected.

<OutputType Condition="'$(TargetFramework)' != 'net6.0'">Exe</OutputType>

Clean and Rebuild the solution. You many need to close/reopen Visual Studio.

The solution still won't build, because the MainPage.xaml is attempting to reference anx external assembly.

Open that file and change the namespace attributes to this:

xmlns:viewmodels="clr-namespace:Maui.Progression.ViewModels"

Clean and Rebuild is now successful!

Run the tests and they pass, like magic.

Pros/Cons

One advantage to keeping all the code in one project is it's a little quicker to navigate.

One disadvantage is there's a tendency toward tighter coupling and worse testing design.

But another, subtler disadvantage is build time. If there are no changes to the UI, and only changes to the dependency projects, the build is substantially faster. This matters when doing test-driven development because we want to keep our feedback loop fast.

You need to decide what balance matters to you.

Wrap Up

We saw how to enable unit testing against a .NET MAUI project directly by building it as a DLL against the net6.0 framework target. There are still challenges in unit testing where the code includes things like SemanticReader calls; I'm hoping to tackle that soon.

Next Up: Build (and maybe deployment), I hope.