DaedTech

Stories about Software

By

I’m Hiring, So Here’s a Job Description

Let me start off by saying that I actually want to hire someone. This isn’t a drill nor is it some kind of hypothetical exercise. I have a real, actual need for .NET software developers and if you are interested in such a job and think that it could be a good fit, please let me know (more details to follow). I think that the pool of people that keeps up with software blogs is the best pool of people there is from which to draw candidates, and I’d go ahead and extend this to the people who run in your circles as well. If you care enough to follow blogs about software, you’re probably the kind of person with whom I’d like to work.

So, the first thing I did was to go and see what was going on at CareerBuilder, Dice, et al. so that I could get some ideas for writing up a job description. I was literally on the second one when I remembered how awkward and silly I find most job descriptions. This bad boy was what confronted me:

Jobs

I was reminded of Blazing Saddles.

Hedley: Qulifications?
Company: NoSQL, Communication Skills, Scala, Communication Skills
Hedley: You said “communication skills” twice.
Company: I like communication skills.

But notwithstanding the double-ups and rambling nature of this and the fact that probably only Horse Recruiter could write it, the ideal candidate has, by my quick count, 27 line items of 1 or more properties. That’s quite a wish list. I’d rather describe what I need like a human being talking to another human being. And, because I’d rather talk like a human being to other human beings, what I’ll start off by doing is describing what we have to offer first, and then what I’m asking in exchange. I think “what we offer” is far too frequently overlooked, and omitting it creates the impression that I think I’m on the Princeton admissions panel for undergraduates, rather than a guy on a team that needs to grow to handle the amount of work we have.

What We Are and What We Offer

Given that this is my personal blog and not affiliated with my 9-5 work, I’m not going to go into a lot of detail about the company, per se. I’ll supply that detail if requested, and you can always look at my Linked In profile — it’s no secret what I do or for whom. Instead, I’ll talk about the group and list out what I think makes it appealing.

We’re a small, agile team and a close knit group. We work exclusively in the .NET space, with a mix of database, application and client side code. Working with us, you would definitely touch Winforms, ASP Webforms, and ASP MVC. We are actively porting Winforms/Webforms functionality to an MVC application. Here are some benefits to working here, as I see them:

  • We follow Scrum (not Scrum-but — actual Scrum)
  • We have MSDN licenses, and we upgrade to the latest developer tools as they are released.
  • You will have creative freedom — we’re too busy for micromanagement.
  • There are definitely growth opportunities for those of you looking to go from developer to senior developer or senior developer to architect.
  • We have nice tooling for Visual Studio development, including NCrunch and CodeRush.
  • Everyone on the team gets a Pluralsight subscription because we believe in the value of personal growth and development.
  • Along the same lines, we have bi-weekly lunch and learns.
  • We have core hours and you can flex your schedule around them.
  • There is no bureaucracy here.  You will never have to write 6 design documents to be approved by 4 committees before you start writing useful code.
  • We practice continuous integration and deployment (the latter to a staging environment)
  • We are at a 10.5 on the Joel Test and climbing.
  • Not software related, but we’re located in Chicago within walking distance from a train stop.

Who Would Be a Good Fit?

Let me preface this with the important distinction that there is no “ideal software engineer” and there is no concept of “good enough” or anything silly like that. We need to ship code and do it quickly and well, and I’m going to look at a bunch of resumes and talk to a bunch of people and then I’m going to take a leap of faith on a person or couple of people that I think will best compliment the team in its goal of shipping code. That’s really all there is to it. You may be the best developer of all time, and I might get this process and wrong and whiff on you as a candidate, and it’s no shortcoming of yours if that happens. I will certainly try my best not to do that, however.

Senior Software Engineer

So, I will now describe the what I think would make someone the best fit for our group. First of all, I’ll describe what we’re looking for in terms of a more experienced, “senior level” candidate, and I’ll describe it quite simply in terms of what I’d be thrilled if I had someone reporting to me doing and doing well.

  • Contribute immediately to a set of different .NET solutions.
  • Can explain sophisticated concepts to less experienced team members, such as generics, lambda expressions, reflection, closures, etc.
  • Lead by example in terms of writing clean code and explaining principles of writing clean code to other developers.
  • Understand Software Craftsmanship principles like SOLID, unit testing/TDD, good abstractions, DRY, etc, well enough to explain to less experienced developers.
  • Versed in different architectural patterns, such as layered and “onion” architectures, as well as Domain Driven Design (DDD).
  • Taking responsibility for and improving our build, ALM setup, source control policies (TFS), and deployment procedures.  We have a good start, but there’s so much more we can do!
  • Can write ASP and the C# to support it in Webforms or MVC, but prefers MVC philosophically.
  • Understands client-server architecture and how to work within that paradigm well enough to explain it to developers that don’t.
  • Is comfortable with or can quickly get up to speed with REST web services and SOAP services, if the latter is necessary.
  • Is comfortable with SQL Server tables, schema, views, and stored procedures.
  • Knows and likes Entity Framework or is willing to pick it up quickly.

Software Engineer (Web)

The other profile of a candidate that I’ll describe is a software engineer with a web background. Again, same description context — if I had someone doing these things for me, I’d be very happy.

  • Come in and immediately start on work that’s piled up with CSS and client-side scripting (jQuery, Javascript) that improves the site experience for some of our sites.
  • Understands C# and server side coding well enough to implement run of the mill features with normal language constructs without asking for help.
  • Good at hunting down and isolating issues that may crop up when there are lots of moving parts.
  • Is aware of or is willing to learn about and explain various model binding paradigms both on the server (MVC) and client (various javascript frameworks).
  • Has a flare for design and could help occasionally with custom branding and the UX of websites.
  • Not a huge fan of Winforms, but willing to roll up your sleeves and get dirty if the team needs help with legacy desktop applications on some sprints.
  • Up for picking up and running with a more specialized skill to help out, such as working with T4 templates, customizing TFS workflows, experimenting with and leveraging something like Signal R, etc.
  • Some experience with or else interest in learning unit testing/TDD as well as clean coding/decoupling practices in general.

Logistical Details and Whatnot

So therein are the details of what I’m looking for. It seems like I’m flying in the face of billions of job ads and thousands of horse recruiters with this approach, and far better minds than mine have probably dedicated a lot of consideration to how to solicit candidates to come interview and how to put together the right set of questions about O notation runtime of quicksort and whatnot. But still, I feel like there’s something humanizing to this approach: this is what we have to offer, this is what would benefit our group, and perhaps we could work together.

In terms of location, I prefer to consider people local to the Chicagoland area or those who are willing to relocate here, but telecommute situations are not ipso facto dealbreakers. If you’re interested in one of these positions or someone you know is interested, please send me or have them send me an email at erik at daedtech, and we’ll take it from there. I’m not exactly sure when I’ll start interviewing, as there are still some internal details to hammer out, but I definitely wanted to give the blog-reading set of developers and people I know the first bite of the apple before I started going through the more common and frustrating channels.

And, also, in a more broad philosophical sense, I wanted to try to put my money where my mouth is a bit. After taking potshots in previous posts at job descriptions and interview processes, I thought it’d be the least I could do to put my own approach out there so as not to be the negative guy who identifies problems and offers no solutions.

By

Good Magic and Bad Magic

Not too long ago, I was working with a web development framework that I had inherited on a project, and I was struggling mightily with it to get it to work. The functionality was not discoverable at all, and it was provided almost exclusively via inheritance rather than composition. Runtime debugging was similarly fruitless, as a great deal of functionality was obfuscated via heavy use of reflection and a lot “squishing” of the application to fit into a forms over data paradigm (binding the GUI right to data sources, for instance). Generally, you would find some kind of prototype class/form to look at, try to adapt it to what you were doing and struggle for a few hours before reverse engineering the fact that you weren’t setting some random property defined in an ancestor class properly. Until you set this string property to “asdffdsa,” absolutely nothing would work. When you finally figured out the answer, the reaction wasn’t one of triumph but indignation. “Really?!? That’s what just ate the last two hours of my life?!?”

I remember a different sort of experience when I started working Web API. With that technology, I frequently found myself thinking things like “this seems like it should work,” and then, lo and behold, it did. In other words, I’d write a bit of code or give something a name that I figured would make sense in context, and things just kind of magically worked. It was a pretty heady feeling, and comparing these two experiences is a study in contrast.

One might say that this a matter of convention and configuration. After all, having to set some weird, non-discoverable string property is really configuration, and a lot of the newer web frameworks, Web API included, rely heavily on convention. But I think it goes beyond that and into the concepts that I’ll call “good and bad magic.” And the reason I say it’s not the same is that one could pretty easily establish non-intuitive conventions and have extremely clear, logical configurations.

When I talk about “magic,” I’m talking about things in a code base or application behind the scenes. This is “magic” in the sense that you can’t spell “automagically” without “magic.” In a MVC or Web API application, the routing conventions and ways that views and controllers are selected are magic. You create FooController and FooView in the right places, and suddenly, when you navigate to app/Foo, things just work. If you want to customize and change things, you can, but it’s not a battle. By default, it does what it seems like it ought to do. The dark side of is the application I described in the first paragraph — the one in which all of the other classes were working because of some obscure setting of a cryptically named property defined in a base class. When you define your own class, everything blows up because you’re not setting this property. It seems like a class should just work, but due to some hidden hocus-pocus, it actually doesn’t.

The reason I mention all this is to offer some advice based on my own experience. When you’re writing code for other developers (and you almost always are because, sooner or later, someone besides you will be maintaining your code or invoking it), think about whether your code hides some magic from others. This will most likely be the case if you’re writing framework or utility code, but it can always apply. If your code is, in fact, doing things that will seem magical to others, ask yourself if it’s good magic or bad magic. A good way to answer this question for yourself is to ask yourself how likely you think it will be that you’ll need to explain what’s going on to people that use your code. If you find yourself thinking, “oh, yeah, they’ll need some help — maybe even an instruction manual,” you’re forcing bad magic on them. If you find yourself thinking, “if they do industry standard things, they’ll figure it out,” you might be in good shape.

I say you might be in good shape because it’s possible you think others will understand it, but they won’t. This comes with practice, and good magic is hard. Bad magic is depressingly easy. So if you’re going to do some magic for your collaborators, make sure it’s good magic because no magic at all is better than bad magic.

By

Beware of Mindless Automation

Something I’ve seen a lot over the years is a tendency to locally maximize when it comes to automating processes. We’re software developers, and thus automation is what we do. But not all automation is created equally, and some of it can be fairly obtuse and misguided if we aren’t careful. And the worst part is that it’s pretty easy to fall into this trap.

For example, let’s say that you observe some people in your organization following a process. They have some Microsoft Word template that they’ve stored somewhere and they regularly open it up and fill it out with data that they pull from an internal system. They populate things like today’s date and various data points and then they do some light formatting based upon various criteria, such as putting items in red if they fall below a certain threshold. When finished, they print out the result, drop it in an envelope, and mail it to another office location of the company. At that location, they process the data and put it into the system — you don’t know too much about that system because it’s not your office location, but that’s the general gist of it.

So, what do you do if you have some spare time and empathy for manual process on your hands and are looking to make a name for yourself? Do you automate this process for them, to their many thanks and heaped praise? And, assuming you do, how do you do it? Do you write some code that pulls the necessary data from your internal system, fires up MS Word interop, and starts automatically generating the documents they’re using? Then, flush with success from that project, do you also automate the printing of the envelopes and metering of the postage?

If you do, how does that go as a function of time? I bet the users are very grateful at first, but then they come to rely on it. And, what’s more, they like the system less and less over the course of time. Every time the USPS changes the price of postage you have to go into this system and made changes, and, what’s worse is that the part that generates the documents seems to break every time there’s a new version or even an update to Word. And when the format of the documents that the other office is requesting changes, suddenly you’ve got a real project on your hands, since automating intricate, form Word documents is about as much fun as spending the afternoon trying to cram a decade of your life onto a one-page resume. Wasn’t this supposed to be helpful? Weren’t you the hero? Does no good deed go unpunished?

Let’s go back to the point where you decided to help. Was the automation as you conceived it worth doing or was it sort of marginal? I mean, you’re probably saving a few minutes for people and some fat-fingering opportunities, but what you still have is sort of an involved, manual process. What if you had stopped to think about the process and the larger goal: getting data from one system into another? Might you not have been talking about things like “web service” or at least “file transfer” instead of things like “Word interop” and “postage?”

Here’s the rub. When your users are solving your problems, they think like users and not like software developers. As such, they come up with non-programming, user solutions. Normal computer users understand MS Word and sending things via mail (or at least email), so they come up with processes that feature those tools. You’re a programmer. By all means, automate, but don’t mindlessly automate whatever they happen to be doing. That’s an optimization tweak. Real software engineering is about using software to create simple solutions to problems. I’ve seen many people fall into this trap and have fallen into it myself. When you’re writing software, asking “why” is invariably more important than asking “how.”

By

Static Analysis: Why You Should Care

I don’t want to go into a ton of detail on this just yet, but in broad terms, my next Pluralsight course covers the subject of static analysis. I get the sense that most people’s reaction to static analysis lies somewhere between “what’s that?” and “oh yeah, we use FX Cop sometimes.” To be sure, it’s not everyone’s reaction, but I’d say the majority falls into this category. And frankly, I think that’s a shame.

To bring things into perspective a bit, what would you do if you wanted to know how many public static methods were in a given namespace or project? I’m guessing that you’d probably hit “ctrl-shift-f” or whatever “find all in files” happens to be in your IDE, and then you’d start counting up the results, excluding spurious matches for public static classes and properties. Maybe you’d find some way to dump the results to Excel and filter or something a little more clever, but it’s still kludgy.

And what if you wanted to answer a question like “how many 20+ line methods are there in my code base?” My guess is that you basically wouldn’t do that at all. Perhaps you have an IDE plugin that offers some static analysis and LOC is a common one, but absent that, you’d probably just take a guess. And what if you wanted to know how many such methods in your code base also took a dependency on three or more framework classes? You’d probably just live with not knowing.

And living with not knowing leads to talking about code in vague generalities where loudness tends to make right. You might describe the whole reporting module as “tricky” or “crappy” or “buggy,” but what do those things really mean, aside from conveying that you more or less don’t trust that code? But what if you could run some qualitative and quantitative analysis on it and say things like “more than 80% of the methods in that module depend on that flaky third party library” or “there are several classes in there that are used by at least 40 other classes, making them extremely risky to change.” Now you have tangible, quantifiable problems for which you can find measurable solutions that can be validated. And that ability is solid gold in a profession often dominated by so-called religious arguments.

CodeReview

Static analysis of the variety that gives you detailed information about your code and warns you about potential problems combines two incredibly useful software development techniques: code review and fast feedback. Code reviews involve peer inspection of code, but it is conceptually possible to get a lot of the benefit of this activity by having the reviewers codify and store common rulesets that they would apply when doing actual reviews: no methods longer than X lines, no more code added to class Y, etc. Done this way, fast feedback becomes possible because the reviewee doesn’t actually need to find time with reviewers but can instead keep running the analysis on the code as he writes it until he gets it right.

There are plenty more benefits that I could list here. I even could talk about how static code analysis is just flat out fascinating (though that’s something of an editorial opinion). But, for my money, it makes the discussion of code quality scientific, and it dramatically speeds up the review/quality feedback loop. I think pretty much any software group could stand to have a bit of that magic dust sprinkled on it.

By

I Don’t Really Do That Anymore

The title of this post has become my answer to a surprising number of things lately and something of an unsatisfying conversation ender. For instance, I was having dinner with some friends the other night, and one of them mentioned a bizarre ‘pattern’ in the code he was working one where people would have a switch statement with a single case (and no default) instead of the more traditional if statement. There was some discussion of this approach as an anti-pattern, and when it was my turn to weigh in, I realized with some embarrassment that I couldn’t really remember off the top exactly how enums behaved in all situations. You see, I don’t really do that anymore. I don’t think I’ve typed “public enum Something {” in well over a year.

This comes up in other situations that I can think of. Someone was telling me about duplication in unit tests. Someone was asking me about cursors in stored procedures. Someone was showing me unit testing troubles they were having around a logger with a public static API. There seems to be an endless list of things to which my response is something along the lines of, “that was a point of ickiness for me too, so I wound up avoiding the whole mess altogether.” Or, more succinctly, “I don’t really do that anymore.”

It’s hard to know when saying something like that if you’re being off-putting and sounding like snot, and, more subtly, it’s hard to know whether or not you might be copping out. I tend to think I’m not, however. I don’t generally shy away from attempts at mastery and generally working toward understanding something. I find that usually I shy away from things that result in flailing without mastery — pain without gain. I never found that using enums resulted in cleaner, better, more defensible code, but I definitely found that using them was a surefire way to make me regret the decision later.

I’ll keep this post short and sweet (as an aside, I’m insanely busy, so I’m trying to gravitate a little more toward posting vignettes). Pay attention to what you find yourself avoiding and see if you can put some reason to it. If there’s some programming practice or construct that makes your fingers subconsciously clench every time you think about doing it, ask yourself why. It may be that a very good explanation or discovery awaits you at the end of some brainstorming and white-boarding. Likewise, if your friends, coworkers or peers in general seem to have developed an aversion toward something, ask them about it or do a little research for largely the same reasons.

We all learned hard lessons as children. After the first time you touched the hot stove, you surely never did it again (at least not on purpose). See if you can pull some wisdom from that stark, simple lesson, and put some solid rationale behind your aversions.