Friday, November 20, 2009

Your Interview -- How to Land a Job as a Software Engineer

Job InterviewThis is the third installment of the How to Land a Job as a Software Engineer series. Now that you've submitted your resume and completed your prescreening, you've been called in to interview.

It's a pretty safe bet that you'll have several interviews to go through including talking to someone in HR, some management folks, and some technical people too. I do the technical interview around here and there are some things I've noticed interviewees do that consistently irk me. Here are things you shouldn't do on a job interview (in no particular order):
  • Don't tell me you don't need to answer my question. I've actually had several interviewees tell me that they don't need to answer my question because it's obvious that they know the answer. If I've asked you the question, it's because I want to know how you're going to answer it. Especially if it's obvious you have no idea WTF you're talking about.
  • Don't bother going if you embellished on your resume or cheated on your prescreener. If you tell me you're a 7 out of 10 with SQL and you can't tell me the difference between an inner join and a left join, I'm not going to hire you. If you tell me you're a 3 out of 10, then you have a fighting chance.
  • Don't ramble. I've only got so much time to talk with you. Most of the time, I enjoy interviewing and I enjoy the conversation, but I really do need to get back to work. Just answer the question I asked and move on.

    Also, as a side note, when I was in graduate school, we talked a lot about interview techniques. The business oriented interviewers are likely to ask you questions like, "What's your biggest shortcoming?" or "Tell me about a time you had a conflict with a co-worker." These are cheesy questions and you're going to have a canned response, so you probably wonder why they even bother asking the question. Keep in mind that these folks have a lot of experience interviewing . . . much more than you do most likely. They ask the question because if you have a canned response, they can catch you off guard.

    Here's the technique. I ask you a question, you give me the canned response, and I just look at you waiting for you to say more. In only seconds, the silence becomes deafening and you start talking again. Now, you're out of your comfort zone and you start telling the truth. The more I nod and keep my mouth shut, the more you confess. Moral of the story? Don't ramble. Just answer the question and then STFU.
  • Don't make things up. If you can't answer the question and you can't make an educated guess, don't just make something up assuming I won't know. I very seldom ask questions in an interview that I don't already know the answer to. If you make something up so that you don't have to say, "I don't know," I can almost guarantee that I'm going to know you're full of it.
  • Don't say you don't know the answer to a question unless you're absolutely sure you know nothing about the topic. Most of the time, I'm trying to figure out where you are in your professional journey. I don't expect you to know everything. Chances are, if you can give me a starting point, I'll prompt you until you get the answer. I just want to get a feel for how well you understand programming concepts. If you simply say, "I don't know" then I have nowhere to start and you don't get partial credit.

    For example, if I ask you the difference between an interface and an abstract class, and you say, "I have no idea" then I have to operate under the assumption that you indeed have no idea. If you say, "well, I know they both define contracts for classes" then instantly you have partial credit. Then I'll ask you, "why would you use them?" You say something remotely intelligent about why you'd want to do this and you have even more partial credit. I'll keep asking you questions until I'm convinced that I've given you as much credit as you can possibly get.

    By the way, this doesn't contradict the previous item. If you make something up and present it like it's fact, I'll assume that you're making things up. If you look at me and say, "you know, I'm not sure, but it sounds like . . . " and then you make your best inference drown from past experience . . . even if you're way out in left field, you still get partial credit.

Thursday, November 19, 2009

The ThoughtWorks Agile Southeast Conference

ThoughtWorksI'm taking a quick reprieve from my How to Land a Job as a Software Engineer series to write about a very informative and enjoyable event I attended this Tuesday. ThoughtWorks held its first professional conference in the Southeast and a friend of mine who is a thought worker invited me to go. It was a well organized event and several noteworthy thought workers presented.

We kicked off the day by listening to a keynote by Neal Ford called, "Why, Not How." Neal pointed out that there is solid evidence that agile works, but that few people investigate why it works. That is to say, the talk focused on why agile works rather than how to work agile. There was a great deal of merit to the things he said about the psychology and biology behind the effectiveness and efficiency of agile methods. This was one of my favorite talks, perhaps because it appealed to my background in behavioral neuroscience research at Duke, my experience getting my MBA, as well as my interest in becoming a better programmer. If only he had said something about airplanes it would've been perfect.

The breakout sessions started after Neal's keynote allowing us to chose between the management track and the technology track. I generally stuck with the management track. Just kidding. But, I wish I could've been in two places at once and I'll explain why shortly.

The first breakout session I went to discussed code metrics, tools for gathering metrics, and ways to interpret metrics. In fact, the significant interest in measurement may be one of my favorite aspects to the agile method. I suppose it appeals to my empirical nature; after all, if you can't observe it, it didn't happen. :)

Next, Anthony Pitluga and Ali Aghareza talked about cloud computing. They made an interesting distinction to me regarding Software as a Service (SaaS), Platform as a Services (PaaS), and Infrastructure as a Service (IaaS). They also pointed out a use for cloud computing that I can really get behind. Just so you know, I think there are very few instances where cloud computing is better than having your own infrastructure, but I believe these fellas were right on when they said it's perfect for testing. I mean, you can spin up (on demand mind you) a full test environment that very closely mimics your production environment on Amazon's EC2. Imagine that! Rather than doubling your capex to get two (or god forbid) three duplicate environments, you just build, test, and deploy your solution to EC2. You bang on it for as long as you need and the whole testing cycle costs a few hundred an hour. Very clever indeed.

I switched over to the management track for Saleem Siddiqui's talk about software complexity. He talked about essential complexity and incidental complexity in software, making a distinction between complexity that has to be in software and complexity that just sort of happens. Then, he talked about why it's better to focus on the latter rather than the former because, well, the former has to be there. He's a well spoken and interesting speaker to be sure.

After that, we took a much needed lunch break and had some really good food (although there was a vegimarian behind me in line who seemed to disagree, but since I'm a meatitarian I didn't notice). During lunch, Scott Conley gave his keynote about Platforms and innovation. As ThoughtWorks Chief Strategy Officer, Scott knows a lot about innovation and he's damn good at talking about it. Despite the incessant tinging of forks on plates, I got a lot out of Scott's talk.

After lunch, I went back to the technical track and enjoyed Graham Brooks's talk about testing web applications. He showed us a framework he's been working on that allows him to apply test driven development techniques to web applications.

Next, Dave Vollbracht talked about the perils of allowing everyone to have a unique development environment. It's important to note, though, that he didn't say anything about being able to try new tools. Basically, he said that if a team member finds a great tool and starts using it, that everybody should have it as well. That way, the machine you are working on may not be the same piece of hardware, but the environment will always be identical. That makes it much easier to image new development machines, to engage in paired programming, or to share team members with other teams. Dave also talked about several methods to achieve this uniformity.

Really, the biggest downside is that I couldn't be in both breakout sessions at the same time. I would really have enjoyed Ross Pettit's talk about Budgeting and the Financial Implications of Agile and I'm sure I would have loved to hear about Gregory Reiser's experience with offshore development. Can agile make offshore development actually work? I guess I won't know until next time.

Speaking of next time, I'll definitely be there and I'll be bringing friends. It was a good conference, and I enjoyed getting the ThoughtWorks perspective. I hope the next one will have a lot more attendance because I'd love to get other perspectives too.

Tuesday, November 10, 2009

Your Prescreening -- How to Land a Job as a Software Engineer

Job InterviewMy How to Land a Job as a Software Engineer series has me inspired and this is the third post I've written today. If you've ever applied for a technical position, you've probably met the prescreening questionnaire before. For software engineers, it generally comprises a set of questions about the language you'll be using and a few puzzles or programming tasks.

My company has something of a prescreening questionnaire and we're working on a more robust one. I've done them in the past and I have several friends who have done them for the companies they work for now. It's a common tool to assess your goodness of fit with the requirements of the position being filled.

So, you get the email from the HR department that says, "Thank you for your resume. You've been selected to move to the next stage of the process. Please complete this prescreening questionnaire and return it. You have one week from today." Sometimes the questionnaire will be online in quiz form and other times it'll just be a list of problems. Sometimes you're allowed to use the internet to help you and other times they ask you not to. In any case, my suggestion to you is to follow whatever rules they give you. Don't cheat! In my post about what hiring managers are looking for in a resume I kind of harped on the whole honesty thing.

Well, I'm about to do it again. Some people have their friends help them with the test or the coding problems or they Google when they were asked not to. Sure, this may help you get the job, but you are setting yourself up for failure. If you cheat on the test, they're going to find out when you go in for the technical interview. If they don't find out in the technical interview, they're going to find out that you're ill qualified once you start working. In any case, you're just gonna disappoint them and there's very little good that can come of it.

Work the problems and do it with integrity. If you don't get the interview or you don't get the job, it's for the best; that job was not for you and you're now better prepared to move on. After you submit your results, study the questionnaire. Learn everything you didn't already know. Then, learn more about what you know. Next time you have a prescreening task, you'll actually know the information you need. When you do get called into that interview, you're going to impress them with your knowledge and capability instead of disappointing them.

Your Resume -- How to Land a Job as a Software Engineer

Job InterviewThis is the first post of a series I call How to Land a Job as a Software Engineer. I chose this as the first post because it's really the first step in the process; however, I do not think it's the most important step because I believe that accolade belongs to selecting the right field in the first place. Also, from your perspective, finding a job to which to apply is the first step; however, I'm writing this series from the perspective of the person who makes the ultimate decision about who is and who is not worth hiring.

That being said, your resume has to be your foot in the door. Let's say that for a given job opening, we receive 100 resumes. At least half of those will be screened out before they even get to me. I'll eliminate at least half of the remaining resumes before we start inviting people to interview.

I've worked with resumes from every angle I can think of. I studied job applications and resumes when I was getting my MBA, I've been a job applicant, and I've reviewed dozens of resumes of job hopefuls. In graduate school, I read chapter after chapter about how a good resume is structured. As a job applicant, I perused every online resource I could find for hints and tricks. As a hiring manager, I can tell you what makes a difference to me.

But, before I get to my tips and tricks, I think it is worth pointing out what happens when a job opportunity opens up. First, the organization has identified a need. Second, the organization publishes that need. Third, many people apply. Fourth, one person is selected.

When you apply for the job, you feel like the organization is trying to hire the best candidate; well, they're not. Don't worry though because they think they're trying to hire the best candidate too; but they're not. In reality, they're trying to eliminate the worst candidates from each phase until there's only one left. I know it's something of a pedantic distinction, but it is important.

Why? Well, when I start looking at resumes, I'm not looking for reasons to hire someone. I assume that if you've sent me your resume, you feel like you'd be right for the job and that the job will be right for you. Therefore, when I look at your resume, I'm looking for reasons you're wrong. I'm trying to eliminate you because I don't want to waste your time and mine by having you in for an interview if I can tell it won't work out.

Sure, there have been times that something really stood out on a resume. Usually, it's a bad thing, but sometimes it's a really good thing. Just, keep in mind that things that stand out don't always stand out in a good way. So, in all forthrightness (and at the risk of seeming petty), here are some of the things that I find to eliminate you from the applicant pool:
  • I don't want to read your 5 page resume. In fact, I won't read your 5 page resume. I'll look at the first half of the first page and the last half of the last page. If you cured cancer in the middle of your career, chances are pretty good I'll never even know about it. If there's something you want me to know, put it in those sections. Even better, keep the whole thing succinct so that I don't think you're verbose.
  • Don't have grammatical or spelling errors in your resume. Ultimately, you're talking about a two page report about a topic you're the only living expert in -- you. If you're writing a doctoral dissertation about a topic you previously knew very little about and a few grammatical or spelling errors slip into the first draft, it's one thing. It's another thing altogether to write a two page paper about what you've been doing for the last 10 years and to make grammatical or spelling mistakes in your final copy. What does that say about your attention to detail?
  • Be factual; don't be boastful. I don't care if you think you're a great communicator or if you think you're an excellent problem solver with 12 years of experience leading successful teams. I just want to know how long you've been at it and what you've done. I'll figure out on my own if you're a great communicator or an excellent problem solver. Besides, how do I know that your definition of a "successful team" isn't one where no more than half of the team quit and 10% of your projects were on time and on budget? In fact, if you put this in your resume, I'm going to tailor your interview to prove you wrong.
  • Tell the truth! I mean, seriously . . . in the name of all things holy and good, don't lie on your resume. If you tell me you have 10 years of programming experience but you really only have 5, I'm probably going to figure it out. As soon as I figure it out, I'm just going to tell you to leave. I'm not kidding; end of the interview. If you tell me you have 5 years of experience and I need a 10 year programmer, you didn't want the job anyway because you're probably not ready yet; however, I'll think, "man, that person was honest and I'm gonna save that resume for the next junior opportunity."

    Most of the time, I just need a programmer of any sort. So, if I'm just looking for a programmer and you say, "I have 5 years of programming experience," and I can tell that you're being honest, I may still hire you; I just won't pay you as much. So, just be honest. If you're honest, the worst that can happen is you don't get the job and everybody's happy (or at least at worst mildly disappointed). If you lie, the worst that can happen is you take a new job, everybody suffers, and you get the ax after your 90 day interim.

Now, here are some positive things I look for in a resume:
  • I actually do care what your hobbies are. I'm not going to hire you based on your hobbies, but if you're up against someone who is exactly equal to you in every way except that your hobbies are cooler, more relevant to the field, or are similar to my own then I'm more likely to hire you. In fact, I once invited someone in for an interview because I wanted to know more about his hobby. Came to find out that he was a very capable engineer, but was just a little too expensive for us. If I had the money, I'd have hired him on the spot.

    It also makes you a real person. I look at a lot of resumes and none of them are real people, but if I know you're into underwater basket weaving, then I'm likely to remember you. In fact, I don't even look at the names on resumes. I just look at the resumes, chose the ones who seem capable, and hand them to my boss saying, "call these in please." If I see that you're into underwater basket weaving, I'll be like, "heh, what's this person's name?"

    So, unless your hobby is rolling your poop into little balls, then go ahead and include a hobbies section on your resume. (Not that there's anything wrong with rolling your poop into little balls; I just don't want you touching company equipment.)
  • I want to see that you stick with jobs for a long time. While I know that contractors will have a lot of short term projects and few long term employments, I really like it if you consolidate your contract work into one item on your resume. Then, you can list the contracts you've worked on under that line item rather than listing each contract as though it was one job. It helps me rapidly review your work history. If nothing else, at least specify that the position was a contract position or I'm going to assume that you can't keep a job longer than a 9 months.
  • Apply for a job that's appropriate to your experience. If you've been programming for 10 years and still consider yourself a junior developer, I'm probably not going to call you back. I know that in most cases, one of two things will be true. Either you're not progressing at your craft and thus aren't worth the investment or you're better than the job you're applying for and you're just going to quit as soon as another opportunity comes up and then you're not worth the investment either. If you should be a senior developer, be a senior developer.

How to Land a Job as a Software Engineer

Job InterviewMy company is hiring again. It's a bittersweet process for me because I love meeting new people and getting new perspectives (and God knows we need the manpower -- er, person-power); however, it is a very frustrating process to endure parsing all of the resumes, selecting the first round for interviews, interviewing, rejecting, being left empty handed.

I started working with Emerald Software Group about three and a half years ago, and have been responsible for evaluating the technical capabilities of our job applicants for the last several years. Sitting on the other side of the table has given me some insight that I'd like to share with job seekers (especially, my fellow software engineers in need of gainful employment).

This is actually the first post in a series of posts about landing the perfect job for you. Nota bene, I didn't say "landing your dream job." I said, "landing the perfect job for you," because your dream job may not be the perfect job for you. For example, my dream job is to drive a Hog for the USAF, but alas the perfect job for me is as a software engineer. I just wanted to make this distinction now because the topic is going to come up again (and again).

Your Resume

I'll be starting with a post about resumes. After all, a majority of our applicants are eliminated before I even see their resumes. Then, I eliminate a majority of the remaining candidates before we invite anyone to interview. I know there are thousands of blog posts out there about resumes, but I want to be completely frank about it. Learn more about what a hiring manager looks for in a resume.

Your Prescreening

Next, I'll discuss the prescreening process. For those of you who don't work in a technical field, you'll probably find this a little foreign. A lot of technical industries have developed prescreening processes to establish your technical capability before you ever set foot in the building. For software engineers, these tend to be basic framework / language questions and some cute and clever programming tasks. I will give you hints to get the most out of your experience with the prescreening questionnaire.

Your Interview

Here's a great place to make an impression (or a great place to really screw it up). A good interview is a precipice. Keep in mind that your interviewer is not looking for a reason to include you in the next round of interviews; your interviewer is looking for reasons to exclude you. The ultimate goal is to eliminate all but one applicant and you want to make sure that it will be you if it should be. Here's how you make sure your job interview goes well.

Your Communication Skills

Communication skills are important even in technical fields. The way that you communicate says a lot about what kind of employee you'll be. People want to know that they'll be able to understand you, that they'll enjoy working with you, and that you'll bring something to the table. We can tell a lot about a candidate by the way they communicate with us. Learn how to communicate effectively and land your software engineering job.

Your Field

I thought long and hard about whether this should be the first post or the last post on the "How to Land a Job as a Software Engineer" topic. It's really the first step, but I've been saving it for last because I have a lot to say about this. I love writing software; if you don't, it'll show. In the post about selecting a field, I'll discuss what we look for when we interview job hopefuls. Selecting the right field for you is the only way to ensure that your perfect job is, in fact, your dream job.

Tuesday, November 3, 2009

Designing a Shampoo Bottle Takes an Engineer

Garnier FructisI was taking a shower this morning when I realized that it takes an engineer to design a shampoo bottle. My fiancee buys this Garnier Fructis stuff. I don't know if it's any good because I'm not smart enough to tell the difference between two shampoos, but she is so I assume it's not bad. In any event, it may have the dumbest design I've ever seen on a product container.

Take a look at the picture of the bottle. You see that little dark greed ball at the top? That's the mechanism for opening the bottle. Now, I obviously don't know in what order you execute your shower routine, but I'd hazard to guess that by the time you get to opening your shampoo bottle, your hands are already wet.

Now, let's say, just hypothetically, that over time a thin layer of soap or shampoo builds up on that stupid little ball. Now, your hands are wet and the bottle is damp and covered in soap and you have to try to pop the top of that bottle by what means? Grabbing? Prying? Squeezing? Try as you may, you can't get a grip on a semi-spherical wet soapy cap.

But, consider what happens over time. When you squeeze the shampoo out of the bottle and then close the cap, you've undoubtedly confined a small amount of shampoo between the cap and the shampoo dispensing opening. This shampoo dries while you're at work somehow morphing into the exact chemical composition of super glue! The next morning, you have to try to un-super glue your shampoo cap by using your wet fingers to apply friction to a soapy sphere.

WTF Garnier? Just, WTF?

Wednesday, October 21, 2009

IComparable.Between Extension Method

IComparableT-SQL has a between statement to make it easier to determine if a test object occurs between two other objects. I needed similar functionality in C# but I didn't know what the type the objects would be; however, I did know they would always be IComparable. Obviously, there's no real need for an extension method here, but it did make things a bit more convenient.

Like T-SQL, the between extension method is inclusive and the start parameter doesn't have to be lower than the end parameter.

Here's what some test cases look like:
5.Between(1, 10) // true
5.Between(10, 1) // true
5.Between(10, 6) // false
5.Between(5, 5)) // true

Here's the method:
public static bool Between<T>(this T target, T start, T end)
    where T : IComparable
{
    if (start.CompareTo(end) == 1)
        return (target.CompareTo(end) >= 0) && (target.CompareTo(start) <= 0);

    return (target.CompareTo(start) >= 0) && (target.CompareTo(end) <= 0);
}

Strongly Typed GetValue Extension Method for SqlDataReader

SqlDataReader GetValue Extension MethodFor a very long time, I've been bitching about the fact that the methods on the System.Data.SqlDataReader class which get a strongly typed result don't have overloads that take column names. I've seen a number of blogs that say, "the reason you can't do this is because you can't overload a method on return type," which is true but irrelevant. I don't see any reason the GetInt32(int i) method couldn't have a GetInt32(string name) overload that handles the GetOrdinal(string name) on your behalf (other than the fact that nobody wanted to write the two dozen overloads.

Well, finding this state of affairs unacceptable, I decided to rectify it. I expected it to be either difficult or annoying depending on the solution I accepted. First, I decided that it should be an extension method because I love extension methods and the fluency they provide. I also decided that it should be generic so you could have one method and specify the desired type. The tough decision came when I was trying to figure out how to handle all of the conversions between types.

Should I switch on the generic type and call the associated method on the SqlDataReader? That is to say, if you call GetValue should I call SqlDataReader.GetInt32 or should I just get the value as an object and handle all of the converting myself? Well, I decided that I'd rather deal with the difficulty of the type conversions than have a big ugly case statement in my method.

Then, I was looking around in the .net classes and found System.Convert.ChangeType and it made the whole process considerably easier. We also had a need to attempt to return the value as a specified type without throwing an exception if it failed (like int.TryParse) so I included a TryGetValue method as well.
public static T GetValue<T>(this SqlDataReader reader, string name)
{
    return (T)Convert.ChangeType(reader[name], typeof(T));
}

public static bool TryGetValue<T>(this SqlDataReader reader, string name, out T output)
{
    try
    {
        output = reader.GetValue<T>(name);
        return true;
    }

    catch (Exception ex)
    {
        if (ex is InvalidCastException || ex is FormatException || ex is OverflowException)
        {
            output = default(T);
            return false;
        }

        else
            throw;
    }
}

// usage examples

// string testString;
// bool result = reader.TryGetValue<string>("ColumnName", out testString);

// int testInt;
// bool result = reader.TryGetValue<int>("ColumnName", out testInt);

// int i = reader.GetValue<int>("ColumnName");
// string s = reader.GetValue<string>("ColumnName");
// DateTime dt = reader.GetValue<datetime>("ColumnName");

Monday, September 14, 2009

Agile Estimating and Planning

Agile Estimating and PlanningA few months ago my company picked up a new project with a fairly major government organization. The mission is to migrate several applications from a mainframe (Natural / Adabas) to a modern environment (C# / SQL Server). We were told that the mainframe was going to be disabled in about 9 months . . . period.

I told the client very early in the process that a typical waterfall approach would be impossible to implement under the conditions of the project and that we should take an agile methodology. The client agreed; however, the lack of resources corralled a few of our team members back to the waterfall approach. After a few weeks in waterfall, we realized that there was no way a waterfall project could be successful in this case.

We officially switched back to an agile approach and the project has been swimming along nicely ever since. I owe a lot of this success to Agile Estimating and Planning by Mike Cohn.

Agile Estimating and Planning is part of the Robert C. Martin Series and is listed in every "Top 10 Agile Books" lists I've found. The book is full of well thought out logical explanations and detailed examples of agile software development practices and principles. It is a very easy read (I read it in 2 days) and the author did an excellent job of relating each chapter to other chapters in the book.

The book begins by pointing out the difference between planning an agile project and agile planning. Next, Mike describes several reasons planning fails in many projects (some of which I discuss in my blog post a few weeks ago called "Programming is a Gas").

The next several chapters discuss the benefits and techniques of abstracting estimations away from time and monetary units. This creates a set of relative estimations based on feature complexity that allows the project room to change over time (and promotes more open and honest communication with the client). Two techniques discussed specifically are story points and ideal days.

The following section is more planning oriented with a detailed discussion of themes, features, and prioritization. There is a discussion about what to do with epics (very large stories) and boundaries on which to split those stories. Conversely, there is also a discussion about combining several small but related user stories into one larger more meaningful one.

The scheduling section describes release and iteration planning, estimating velocity, and techniques for buffering projects (especially risky projects). the tracking and communicating section gives you a set of methods for monitoring the release and iteration plans and a tool set you can use to communicate this with the project stakeholders.

The next section describes how (and why) agile projects work so well in real life. High visibility into the project, frequent feature based planning, and small story size make agile projects preferred for many software development groups as well as many clients who have had the good fortune to have experienced a well run agile project.

The final chapter is a hypothetical case study which demonstrates the entire agile software development life cycle from beginning to end. In this chapter, you get to see how an agile project begins, how stakeholders become involved, how iterations are planned, and how easily problems can be solved. If you read carefully, you can also pick up a lot of insight Mike has to offer from his experience as an agile coach.

You can purchase Agile Estimating and Planning from Amazon.com at a deeply discounted rate.

Thursday, September 3, 2009

Head First Design Patterns

Head First Design PatternsI read Head First Design Patterns about a year ago and it changed my life. Now, I know that a lot of non-programmers read this blog and I'm sure you must be thinking, "how can a book, especially one like that, possibly change your life?"

Well, it made my code much cleaner, much more flexible, and much easier to write. That's why I decided to make this the first book review on this blog. First of all, I'm a pretty big fan of the Head First style. I like most of the jokes and intentional thought provoking. It's a clever way to help people understand and remember what they're learning. Admittedly, sometimes it goes a little overboard, but I'd rather it go a little overboard than be a dry read. I read almost the whole book on a road trip from Atlanta to Orlando.

The book sets out to give the reader an understanding of what a design pattern is and what it's good for. A design pattern is a template for solving commonly occurring problems in software design. Head First Design Patterns discusses the details of about 15. You'll be surprised how many of these patterns you've seen before (and may have even written before). One of the big benefits you get out of this book is a common language to describe the patterns in your code. Next time you're doing a code review, you'll find yourself saying things like, "this is just a singleton" and your reviewer will understand what you're trying to accomplish without discussing the implementation details.

After reading this book, I've noticed more and more patterns:

The decorator pattern that you see throughout the .net framework. There are a lot of classes that take a stream and return a stream. Some read, some write, some encrypt — all of them are decorators.

The proxy pattern controls access to other objects. I wrote a blog post back in December of 2008 where I used the proxy pattern to write to multiple TextWriters.

The singleton pattern ensures that a class has only one instance and has a global point of access. It bears noting that there are a lot of programmers who have criticized the singleton to which the singleton replied in a public statement last year, "you can kiss my ass." It is true that the singleton can come back to bite you if you use it incorrectly; the singleton is the right tool for the job it has. Head First Design Patterns helps you understand what exactly that job is.

The template method pattern popped up the other day when I was looking at some PostSharp aspects. If you use the OnMethodInvocationAspect like I did with my memoizer, PostSharp will produce something very similar to a template method. Obviously, PostSharp isn't creating a base class and then overriding the template method, but it is allowing you to control the flow of the method without having knowledge of the method implementation.

The factory method and abstract factory patterns are also quite common and are well described in Head First Design Patterns. People use these patterns all the time. I've seen many data access layer implementations where a factory method loads a particular data access provider based on configuration options. You can achieve the same results with inversion of control containers like Ninject and autofac, but sometimes you just need a quick factory.

Almost every review I've seen of Head First Design Patterns has been positive; however, every once in a while you find a detractor like Jeff Atwood in his blog post from 2005. I think Jeff is probably a good guy and a good coder; he's just contrary and cynical. I know that being contrary and cynical doesn't negate your point, but it is a bit like crying wolf. I'm not going to address his argument in this post (because I could dedicate an entire post to the argument if I thought it'd do any good), but I think you should read it because he does have one some valid points.

Unneeded complexity is bad. I wouldn't say that design patterns should be eschewed altogether, but you should use the right pattern for the right problem. Reading this book should teach you to identify patterns yourself. What are some common problems you run into in your field? Can you think of a pattern for addressing these problems?

You have to learn to abstract your knowledge and apply it practically. Don't just decide that patterns are bad and start knocking books because the graphic on the cover has been reused. A pattern doesn't have to be necessary to be valuable. When the pattern provides maintainability, readability, testability, or simplicity then use the pattern; that's what it's there for. The pattern is just another tool in your tool belt.

I very seldom recommend you throw a specialized tool away just because you don't need it all the time. Buy (or borrow) Head First Design Patterns and focus on learning how to recognize and solve common problems. You won't regret it.

You can get Head First Design Patterns from Amazon.com for a great price.

Sunday, August 30, 2009

Understanding Tax Brackets Takes an Engineer

Tax Bracket GraphI've talked to dozens of people who have a dramatic misunderstanding of tax brackets (or tax rate schedules). In fact, I think I've run into more people who misunderstand how taxes work than who understand. So, I thought I'd demystify one small part of the American income tax system — brackets.

Many people believe that shifting from one tax bracket to another yields a major leap in income tax. This is incorrect. When you move from the 15% tax bracket to the 25% bracket for example, you're not suddenly paying an additional 10% in taxes. That is to say that if you make $33,950.00 per year (the highest salary for the 15% bracket) and you get a 1 cent raise bumping you up to the next tax bracket, that your change in income tax will actually be zero dollars.

Here's how that works. If you're in the 15% bracket, you pay 15% on income above $8,350.00 and you add $835 to that. The next bracket up is for people who earn more than $33,950.00 and less than $82,250.00. They pay 25% on income above $33,950.00 plus $4,675.00. Now, here's an interesting observation. If you take 15% of $33,950.00 - $8,350.00 (the maximum for the 15% bracket) and add $850, you get $4,675.00. That means that the maximum for the 15% bracket is the same as the minimum for the 25% bracket.

Thus, there's not a major leap between brackets. So, what are brackets for? Well, basically, the tax bracket just defines the rate of change between the minimum and the maximum incomes in the bracket. If you remember taking algebra back in the old days, you're just talking about slope. Basically, your tax bracket defines the slope of the line on which your tax is determined from your income.

Consider the slope-intercept form for a line: y = mx + b where b is the y intercept and m is the slope. If you look at the graph at the top of this blog (created with a free iPhone app called grafunc by Fabio Policarp), you'll see a blue and an orange line. The blue line represents the 15% bracket using the equation y = .15 (x - 8350) + 835 and the orange line represents the 25% bracket with the equation y = .25 (x - 33950) + 4675. Where those two lines intersect is where you switch brackets.

That's about all there is to understanding tax brackets. There's much more to understand about taxes, but that's another blog post altogether.

Wednesday, August 26, 2009

Programming is a Gas

gasProgramming is a gas. I don't mean programming is entertaining and exciting (even though sometimes it really is); I mean more along the lines of the physical state of matter. Programming is a gas. You see, a gas having perfect mobility and infinite expansion will take the size and shape of the container you put it in.

Parkinson's Law states that "work expands so as to fill the time available for its completion." I'm taking this one step forward and saying that "software development expands so as to take the size and shape of the constraints placed upon it."

I've worked with tens (if not hundreds) of software engineers and I can tell you one thing with certainty: ceteris paribus, the more the engineer charges for services, the better the result. Now, obviously, some engineers misrepresent their skill level intentionally or unintentionally, but . . . on average . . .

So, if this is the case, you can put several of these programmers together and derive that the more you pay a software consultancy, the better the result as well. I know to some, this probably just sounds obtuse. You might be saying to yourself, "well, some companies just have higher profit margins than others." 'tis true; some programmers have higher profit margins.

If you've been at the top of the game for 10 years, you deserve more than someone who just started programming (or someone who has stagnated for 10 years) because you can apply all of your experience to each new project. Similarly, a software consultancy with premium engineers (no matter how old the organization) can earn a higher margin because its engineers produce such valuable results.

Understanding this stipulation (whether you agree or not) is pivotal to the rest of this post, so I'll very briefly summarize what I'm saying: you get what you pay for!

So, why do so many projects turn sour? If you're a software engineer, think of the last 10 projects you worked on. If you're not an engineer, think of the last 10 projects your company had someone else work on. What's the first step of all of these projects? Almost uniformly, it's an RFP and if not an RFP per se, it's some kind of competitive bidding process.

That's where the situation starts going south — before the project even gets kicked off! Have you ever had a project where the vendor wasn't selected almost exclusively based on cost? When was the last time someone said, "whichever vendor comes back with the best feature ideas will get the contract" or "whichever vendor has the lowest turnover rate and the highest employee satisfaction will get the contract?" In fact, in a perfect world, I believe you could select a vendor based on its mission statement and core values (and perhaps a brief summary of its gestalt experience).

inscribed circlesAlmost every project I've been on has had two constraints . . . money and time. Before a pen ever touches the signature line on the contract, the project is doomed. The shape of the project is defined by money and time, not by desired features.

Thus, when a developer looks at the project, it is going to take the shape of money and time; however, to the customer, the project is expected to be shaped by the desired features. More often than not, the money x time shape fits quite neatly inside the feature shape.

So, what exactly am I proposing? I'm proposing that the team (whether it is internal or external) should be chosen based on values and trustworthiness. A team you can trust is much more valuable than a team which is cheap. Take the team you can trust and then define the shape of your project based on the features you want to see. When you ask the team for an estimate, it's not to compete for the project; rather, the estimate is so that you'll know if you have the budget for the project in the first place.

If you do it this way, you'll get an honest estimate. Many software companies will low-ball estimates because they know that once you're committed to the project, you'll dedicate whatever additional resources are necessary to complete it. Ultimately, it'll end up costing more in the long run because of the way each "phase" will build on the "phase" before it compared to a solution that was well architected from the get-go.

Thursday, August 6, 2009

iPhone Bookmarklet Installer Source

iPhone BookmarkletsA few hours ago, I posted my iPhone Bookmarklet Installer Bookmarklet and several people have asked how it works.

Well, it's pretty basic. The effort is to loop through all the links on the page, identify the bookmarklets, and modify them so that the bookmarklet is appended to the URL somehow. The first time I tried, I used the '?' character making the bookmarklet look like a query string. This proved problematic though as a number of bookmarklets failed to convert cleanly. I didn't really investigate but I'd imagine it has something to do with the '&' character and/or '=' signs.

In any event, it's pretty easy to fix that by using the '#' character instead of ? because then it just looks like an anchor. It also keeps the page from having to reload. So, all you have to do is run the bookmarklet on your iPhone, click the bookmarklet you want to install, save the bookmark and remove everything up to and including the #.

Now, the actual bookmarklet code has been scrubbed a little to give it something of a smaller footprint like this:
(function(){
var s,i,l=document.links;
for(i=0;i<l.length;i++)
{
if(l[i].href.indexOf('javascript:')!=0)
continue;

l[i].href='#'+l[i].href;
}
})();

But, that's a little hard to read, so here's the pre-scrubbed version. There's also an additional section I added later to make it easier to identify which links have been transformed (i.e., which are identified as bookmarklets). Here's the code:
// anonymous function
(function(){

// put the link array somewhere
var links = document.links;

// loop through all the links
for (var i = 0; i < links.length; i++)
{

// if the link does not start with javascript:
// it isn't a bookmarklet and we can exit this
// itteration and continue the loop
if(links[i].href.indexOf('javascript:') != 0)
continue;

// update the href of the link prepending the
// '#' character to make it look like an anchor
links[i].href = '#' + links[i].href;

// add some styling information to identify the
// modified links
var style = links[i].style;
style.backgroundColor = '#eee';
style.color = '#333';
style.border = '1px solid #333';
style.textDecoration = 'none';
style.padding = '2px';
style.fontWeight = 'normal';
}
})();

iPhone Bookmarklet to Install iPhone Bookmarklets

iPhone BookmarkletsAs a software engineer and a web developer, I have really grown to love the bookmarklet. I have a Regex Search Bookmarklet, my favorite javascript shell bookmarklet from Jesse's Bookmarklets, and of course, you've seen my blog post on Tabulate from the clever folks at Inventive Labs. However, installing bookmarklets on the iPhone without help from a computer is a royal PITA.

That's why I wrote the iPhone Bookmarklet Installer.

If you're interested in how it works, you can find details on my iPhone Installer Bookmarklet blog post. But, the short version is that I use Javascript to loop through all of the links on the page and make them look like anchor tags so you can just bookmark them on the iPhone and remove everything before the anchor tag character '#'.

With that out of the way, here's how you use it:
  1. Run the bookmarklet on this page by clicking the iPhone Bookmarklet Installer. You should see all of the bookmarklets on this page change styles (They'll look something like this).
  2. Click the bookmarklet you wish to install (n.b., the page won't reload).
  3. Bookmark the page.
  4. Edit the bookmark and remove everything up to and including the # character.
  5. Name the bookmarklet appropriately.
  6. Save and enjoy.

Friday, July 10, 2009

Leave the Poor Table Alone

Traffic SignSo, I realize that with some clever hacking and a butt-load of time, you can do just about anything with divs and CSS, but I think the anti-table thing has gone way too far! I've even seen people display tabular data without using tables. I mean, great. Look at you. You're fancy and all, but what have you accomplished? Tabular data is what tables were designed for in the first place.

So, why are people so steadfastly opposed to tables in HTML layout? Well, I've seen oodles of reasons including things like speed of data transfer, separation of content and layout, ease of redesign, no spacer gifs, lower html complexity, accessibility for persons with disabilities, etc.

Of course, there are sites out there that demonstrate all of the things that can be accomplished using nothing but divs and CSS and they're really great to look at and enjoy; I've learned a lot about CSS from them. But, just because you can doesn't mean you should. I mean, when was the last time you heard about someone doing something with "nothing but" and it wasn't a stupid human trick? Mac Gyver could take down a swarm of enemies with nothing but a Milk Bone, some shoe string, a little fertilizer, and duct tape; I, on the other hand, carry a Glock.

But, here's the real issue: whether you use tables or not, there're right and wrong ways to do anything. Just like there are wrong ways to use tables for layout, there are wrong ways not to. My point is that you can very cleanly and appropriately use tables for layout and still use CSS for almost all of your actual presentation.

As a result, I've yet to come up with a compelling reason to eliminate tables from layout altogether. For example, using a table for your overall layout can give you cross browser compatibility that is very difficult and effortful to achieve with CSS and divs. CSS and DIVs are rendered differently among the several browsers; however, CSS and tables are relatively consistent.

I've found that often times, I can use only one table and achieve exactly the layout I was looking for when a div design would require 3 or 4 levels of nesting. In this case, it is actually cheaper and less complex to use tables than it is to use divs and it took me a tenth of the time.

While I agree there should be a separation of concerns within the definition of websites to keep content, presentation, and behavior separated, using tables to position elements only is a very minor violation of this principle. In fact, using tables in this way is exactly the same as using divs this way. Afterall, any time you use an HTML tag your intent is to describe something about the way the content is displayed. Then, you modify that behavior with CSS. Really, the only thing you can't do with tables and CSS is fundamentally change the position of items.

I suppose that's where people are coming from when they mention redesign. Now, that may be the case and I don't really know that much about it. I'm not a web designer; I'm a software engineer. I spend a very small percentage of my time concerned with layout as there are usually much bigger fish to fry; however, I've never been on a redesign project that didn't require HTML changes.

As a result, it never made a difference whether the page was tables + CSS or divs + CSS; we always had to rewrite some HTML. Furthermore, it's generally in a template somewhere. In fact, many times, it has been easier for me to reposition elements on a page because I was using tables for layout rather than divs. The CSS required to move stuff around and make it cross-browser compatible is often a royal pain in the ass, but it's pretty easy for me to move a one line server side include or a user control in .net.

I never really understood why people used spacer gifs. I don't use them and never have so I don't know what that has to do with tables. I also don't know what tables have to do with accessibility. I've read some things about readers not being able to do anything with graphics because they can only interpret and present text. Divs, tables, plain text, whatever . . . it's all the same text so I don't really know what this has to do with tables for layout.

In my years of experience, I've gone through the dogmatic anti-table phase and I've gotten over it. I simply cannot come up with a good reason to eschew tabular layout. Most of the time, I can do what I want with divs and CSS and I do. When something is difficult with a div, I usually throw a table at it. As a result, I get the job done faster and I save clients money and they ultimately get the same quality software. I've also not had any complaints about accessibility, maintainability, or load times. To me, it's a win-all-around kind of thing, so until I can find solid arguments against tables, I say leave the poor table alone. It's another tool in the toolbox; use it if it makes your life easier.

Monday, July 6, 2009

Sign Placement Takes an Engineer

Traffic SignI was driving into work this morning and I noticed a sign off to my right. It was a temporary sign which evidently was warning us drivers of some upcoming event. It was too small to contain the entire message so they broke it down into pages which displayed for about 3 seconds each. The first page I saw read:
July 12, 2009
From 6:00 AM
To 7:00 AM
Interested, I eagerly awaited the next page. About 3 seconds later the sign read:
Between
Exits 6 and 7
But, before I could find out what was happening during that block of time, I passed the sign. What in the world did that third page read? Should I plan on staying home? Should I leave home? What's happening?

Well, I started thinking about it and it occurred to me that it was pretty dumb to put that sign on the side of the road right after a curve. Why not put it after the curve in the ensuing half mile straight away?

So, I looked into it. If you take a look at the image above, you'll see the approximate location of the sign. I drew a line segment starting at the sign, passing the west most occluder, and ending at the median between the northbound and southbound lanes.

Then, I traced the median all the way up to the approximate angle where I could no longer see the sign because the visual angle was too narrow.

Next, I traced the fast lane (the longest route within the "polygon of visibility"). I measured it out in google maps and it turns out that the sign was visible for 448 feet.

The speed limit at this point on GA 400 is 65 miles per hour (approx. 95 ft / s). That means that the sign was visible for just shy of 5 seconds.

I'm sure by now, you've done the math and come to the same conclusion. If the sign pages rotate at a minimum of 3 seconds per page and the maximum visible time at or above the speed limit is 5 seconds, then it is only possible to read 2 pages of data. However, the message must be at least 3 pages in order to be complete.

There's no way to reasonably expect drivers to read the entire message and therefore most people passing that sign today will have no idea what the full message is. Evidently, when it comes to sign placement, it takes an engineer.

It Takes an Engineer

EngineeringI'm pretty excited about this post. Not only is it my first blog post in a while (I've been pretty swamped lately and haven't had a chance to write anything), but it's also the first new section I've started in a long time.

This entry marks the first post in a series of posts I call, "It Takes an Engineer." It's about all of those things we see in daily life that would be better if they consulted an engineer first.

I'm sure, if you're reading this blog, you probably know what I'm talking about. It's the stuff that makes you stop and say, "what the hell were you thinking when you did this?" Or, "you really thought this would be intuitive?" Or, "if someone thought about how this was going to be used, I wouldn't have to fix it all the time."

Well, this is going to be my venue for venting on this topic so I hope it provides enjoyment to all. If you have anymore good examples, let me know and I'll blog about them too.