Thursday, August 7, 2008

In defense of “old, tired” tech interview questions

“What’s the difference between an abstract class and an interface”

“Define polymorphism”

“What’s the difference between a value type and a reference type (primitive and object)”

“How is an object different from a class”

I had a conversation with a fellow Improver a while back where we discussed object oriented and development questions often asked during tech interviews. My colleague had a low opinion of these questions for reasons you might expect: people have rehearsed answers, they don’t necessarily test knowledge that is relevant to being a talented developer, they make you look like a tool because they’ve already heard the question in every other interview, etc. I tend to ask this type of question from time to time because I find them very interesting, but since our conversation I’ve been wondering if I should discontinue them. I’m hoping for some feedback on whether or not the questions have any merit, but first, here is my defense.

- General reasons to ask these questions
• I mostly ask these questions to junior candidates, not all of them have heard them a thousand times.
• After they answer, I usually ask them if they’ve had that question before (people are very eager to say yes if they have, not sure why), if they have and they still don’t have a good answer, that’s a good data point.
• If someone rolls their eyes or scoffs at the question (it’s happened to me), that’s a good data point. Politeness, restraint, and tact are very important to teamwork and client relations, an eye roll indicates arrogance or at least lack of restraint. If you want to work here, don’t act like my questions are beneath you.
• If these questions are so simple and pedestrian, how come so many people don’t have an answer or answer them badly?
• Every once in a while someone gives me an excellent response showing particular insight. If someone teaches you something new, really makes you think, or turns “What’s the difference between an interface and an abstract class” into a master class on object oriented development, you probably should hire them.
• Most of these questions have several levels of depth, the answer they give tells you a little about how they think, more on this later.
• If the candidate has a canned answer, you can throw them off guard with an insightful follow up and tell whether or not they actually understand what they’re saying. If the candidate is trying to BS you, this tells you something about the way they operate.

- Detailed defense of a couple choice questions

- “Define Polymorphism”
• This isn’t just a vocabulary quiz. That being said, whether or not they’ve heard the term is a data point. If they’ve heard the term but still don’t know what it means, that’s a data point as well. If they tell you straight up, I’m not familiar with that term, 0 points deducted, if they try to BS you, -10 points. If they are unfamiliar with the term you can explain it, then give them an example and have them predict the behavior, hopefully they catch on fast and recognize it from their development experience. You can see the epiphany, if they don’t recognize the behavior once you’ve worked through the example, they are missing some basic OO knowledge. No one cares that it means “many forms”, at least I don’t, tell me what it means in object oriented programming. Some people must be impressed by the etymology of the word because a lot of people make sure to include that in their answer (not necessarily a data point, but is interesting nonetheless). There are two forms of polymorphism, overloaded methods and overridden methods, I like it when they mention that. If they mention only one, you can ask them about the other. This is also an easy way (depending on the target language) to segue into a discussion of virtual methods, C#’s “new” keyword, abstract classes, etc. Some candidates have a one sentence answer, some give you an example, some discuss both types of polymorphism, etc. These all show you a little bit about how they think.

- “What’s the difference between an interface and an abstract class”
• I have to admit, I don’t really like this question. I prefer to ask them to define one, then the other and discuss the merits of loose coupling, the impact of inheritance on the rigidity of your object model, etc. But the spirit of the question is the same no matter how you structure it. Discussing these concepts at the definition level allows you some insight into the way the candidate considers these constructs and the value they place on them. Some people don’t have much to say about interfaces because they haven’t built very many (not good). Some people have well defined scenarios in their mind for when each construct is valuable, this indicates a mature sense of object-oriented design.

Many other common and overly-asked questions provide merit for similar reasons. I’m always interested in hearing the questions people ask, and why they ask them. I don’t subscribe to the belief that just because a question is asked often that it is a bad question. In fact, the opposite is likely true! Maybe some people just don’t have good reasons for why they ask them?

Thursday, July 10, 2008

Kobe, Tell Me How My Apps Taste!

I think it's very pathetic how awesome this day has been for me. The iPhone software 2.0 was "released" today (more like "found on Apple's servers"). And I've been playing with all of the cool free and non-free apps I downloaded. My favorite so far is, of course, OmniFocus for iPhone. I feel like I've been waiting my whole life for my iPhone to support my GTD lifestyle and now my system is finally complete! ... except MobileMe has been down all day so I can't test my automatic, Exchange-less, over-the-air syncing of contacts and calendar, but that just gives me something to look forward to! So far, OmniFocus' iPhone application has far exceeded my expectations, we'll see what I say about it next week. ;)

If you don't have an iPhone, go get one! The AppStore is the missing killer feature of the iPhone and there's nothing like it for any other mobile platform. Way to go Apple!

Labels: ,

Wednesday, June 25, 2008

Is Outsourcing a Good Idea?

I've been doing a lot of thinking about when/why a company should outsource application development. Our Rural Sourcing offering at Improving is a perfect solution for companies looking to outsource custom development, but I wonder if I would be acting in my customer's best interest if I were to council them to choose outsourcing a large, long-running development project to Improving rather than staffing up internally and executing the project in house. Here is a bit of the conversation I've been having with myself:

Outsourcing offers several clear advantages:
  • No hiring/onboarding necessary. This is important because recruiting/hiring is an expensive proposition and a long-term commitment. A company can potentially save money by outsourcing if the project is sufficiently short by avoiding recruiting costs and avoiding down-time for full-time staff when there's not an expectation of continuing need.
  • Opportunity to gain access to specific skills/knowledge. Training existing employees could be more expensive and time consuming than hiring a consultant that already has the desired skills.
  • Assumption of risk. If the contract is structured in a way where a consulting company is penalized financially if the project delayed or missing expected functionality, some of the risk of a development project is transferred to the consulting partner.

"So what happens if the project is longer and transfer of risk is not important to the client? Is there a conflict of interest for a technology consultant between his/her employer's desire for continued/long-term business and the customer's desire for a quality product at the lowest cost?"

The answer is yes, in some cases there might be. Traditionally, outsourcing application development is more expensive on its face than developing an application with available internal staff because the consulting company is in the business of making a profit.

"So, what do you get for that extra cost?"

In our case what you get is a highly functional team and superior development practices that produce a higher quality product in less time. Even though the cost per hour is more, the actual cost and total cost of ownership are dramatically decreased.

"That sounds great! Except wouldn't it be even better if the customer made THEIR staff highly functional and incorporated those superior practices into THEIR organization so they can produce all of their software with our efficiency and less cost using staff that already has the necessary domain knowledge?"

In most cases I think it absolutely would, if delivery of the particular application in question is not extremely time-sensitive (the transition, of course, doesn't happen over night).

To be a full-service consultancy and a quality partner to its clients, Improving offers training, mentoring, and outsourced application development and our corporate values state that we're always happy to work ourselves out of a job.

"Whew! So much for that conflict of interest! But does that mean I should recommend mentoring in agile practices over outsourcing?"

Perhaps yes if we're talking about traditional outsourcing and the organization is prepared to adopt a more agile philosophy (that's a whole other conversation!). The interesting thing about Rural Sourcing is the concept of being able to provide ALL the advantages of outsourcing at an hourly price comparable or even less than developing the application internally.

The conclusion I've been able to come to is that Rural Sourcing is definitely a valuable service offering for my customers and I have no problem feeling good about recommending it every chance I get as long as I'm confident we can produce a top-quality product using a highly effective agile team at a low cost. With that formula I think everyone should send their projects to the Rural Shore :).

<-- Rural Shore of Lake Bryan, Near our Rural Sourcing center in Bryan/College Station, TX

Labels: ,

Wednesday, March 5, 2008

Get the most out of your team - 7 easy ways to promote buy-in

There are a myriad of methods IT managers use to try and increase their team's productivity, some are good and some are terrible. One of the best ways to increase productivity is to maximize the team's sense of personal ownership of its goals.

1) Have the team make its own estimates all the time, and be very careful not to pressure them into modifying those estimates. If you're curious about the reasoning, ask for elaboration, but never indicate you disagree. If you're in a position of authority they may not have the courage to argue with you (they should, but that's another discussion).

2) Promote pride in the product by letting the team set and enforce the quality standards they agree upon. Have a damn good reason for discouraging refactoring if the team thinks it's necessary, and always schedule it with high priority for the near future if it can't be done now. There's ALWAYS time for unit testing, and be proud of a team that demands high standards, even if you think it's negatively impacting the schedule (it's probably not, but, again, that's another discussion.

3) Allow for time-boxed investigation of alternative ways of accomplishing a goal. This goes along with point number two; it helps the team feel like it is invested in its own technology decisions, thus increasing their sense of ownership. It sucks when you feel like you're wedded to a technology or approach that you were rushed into and, in hindsight, was obviously not the best solution. Eventually you'll disengage and feel powerless.

4) Make sure everyone gets involved by forbidding the flipping of the bozo bit. Make it abundantly clear that there are no stupid ideas or questions and actively encourage both from every team member. Have a culture of politeness and respect. The more confident a team member is that they are contributing, the more pride and ownership they will feel in the solution.

5) Limit panic and mass hysteria. Most of the time your software delivery schedule is not life or death. Excess pressure and forced weekend work is the black plague for software teams, it festers into disengagement and burnout much quicker than you think, then you're hosed. Better to slip a deadline and reestablish expectations early. Plus, if you've got a highly invested team, they'll sense the urgency and place the pressure upon themselves.

6) Unless there's an overwhelming reason not to, give the benefit of the doubt to the technology preferences of the team. A team enjoys using new and exciting technologies and tools. Sure, there's some risk that needs to be understood, but don't forget the non-obvious advantages to using the latest and greatest. Team members appreciate getting exposure to the latest technologies, it's good for morale and they'll be better engineers as a result. A team is always more productive when they enjoy their work, and working with the technologies they're interested in will help accomplish that.

7) All problems are the teams problems, don't play the blame game. When a production issue comes up that becomes the team's top priority, the first step is not to figure out who's fault it is, the first step is to fix the problem as a team and understand that stuff happens. After the problem is resolved, the next step is to figure out how to improve your standards and processes so that you can decrease the likelihood of such problems recurring (finger pointing and passing the buck should not be one of the steps). Any problem with the system becomes the team's problem, not an individual's problem.

Labels: ,

Friday, June 29, 2007

A lean approach to course-building

A few years ago I worked with an organization to build computer-based-training modules to teach Java. My team and I worked with a professor from the Education Psychology department at Texas A&M to study how computer-based training could actually be effective. I think these ideas are equally as applicable to instructor-led training.

The challenge was to include content in the course if and only if it added discernible value toward the course's objectives. To make sure the progress is discernible, we used a method of task-analysis to iteratively define finite activities for each task until we reached an elemental task in each branch of the tree. What you tend to end up with is a tree of dependent objectives and activities that describe everything needed to accomplish the goal of the course. In addition, each sub-objective directly correlates to a parent objective that implicitly provides value toward the ultimate purpose of the course.

This top-down approach to lean course development involves a lot of questions to determine the next activity, etc. I made a note of a few of the questions I tend to ask myself and thought I would share them.

* Determining the root node of the task analysis tree
- Why are we offering this course?
- Why will people pay money to attend this course?
- What do customers expect to get from this course?
- What would make customers recommend this course to their peers/friends?

* Determining the children of a particular node in the task analysis tree
- What do you have to know before you can... (perform parent task)
- What action could someone perform to demonstrate that they know how to...
- How do you know they understand how to...
- Does the ability to perform... get someone closer to being able to... (for each parent node)
- Does this ad discernable value toward the objectives above?

When this process is followed rigidly, the result is a very interesting arrangement of shapes that lend themselves very easily to chunking into sections. Start with the lowest clump of activities, moving up the tree and you have the sections of your module/course. The root of each section can be your course objectives, and the tasks inside each section can be the objectives for that section. The objectives are finite and measurable and represent distinct value to your customers. Plus, the objectives are fine-grained, concrete, and comprehensive enough that it is easy to strictly tie the content of the course directly to those tasks.

This is a simple task analysis example I did for a computer-based training module on Java methods [http://ahurst.com/images/methodsTA.png]

Labels:

Wednesday, June 27, 2007

Price is what you pay, Value is what you get.

I got my new business cards today.  Our business cards at Improving are unique, they are customized for each person including pretty much whatever text each employee wants.  My cards include a quote from Warren Buffett: "Price is what you pay, Value is what you get."

I heard this quote a couple years ago and it has really stuck with me.  I know what it means to me, but I decided to google it today, just to see what others had to say about it.  I found a 2003 post from Business Journal [http://www.bizjournals.com/milwaukee/stories/2003/02/17/smallb6.html] that made a good analogy using a dentist.  A more in-depth article at sideroad.com [http://www.sideroad.com/Marketing/creating-value.html] gives an analysis of the relation between cost and value.

I think the quote applies especially well to software development.  More than most professions, software development is a very volatile undertaking.  An organization that can reliably deliver quality software is extremely valuable.  If they can do so faster than their competitor, they are even more valuable.  Then why is it software consultants are paid by the hour?  This is my fundamental problem with time and materials contracts for a consulting organization.  If companies were more thoughtful about price vs value, they might consider paying a little (or a lot) more for a high-quality software organization to develop their software at a fixed price.

Saturday, June 9, 2007

Subversion branching/release management

I'm continually surprised at how much discussion exists about how to manage releases and development branches in enterprise source code repositories. Many of the smartest, most experienced people I've worked with have come to the same conclusions about the best way to manage a source code repository. I suppose I just assume that everyone in the industry has accepted these strategies as a best practice, but maybe I'm wrong! I enjoy working with subversion the most, so my analysis assumes it is the tool being used to manage the repository, although the ideas can be generalized to most SCM tools.

I prefer to use this classic structure:
/repository/branches
/repository/tags
/repository/trunk

There are a few basic principles that define my preferred approach to SCM:

1) trunk is king. 98% of new development should be done against trunk.

2) trunk is always golden. All code builds and all tests pass all the time. Use a continuous build system to make sure trunk always works. Use a code coverage tool to make sure untested code breaks the build. If it's not tested, it's not complete and it should not be checked in.

3) Update often. Since trunk always builds it's easy to update, do it so that you're not working against stale code and merges become easier.

4) Check in often. Each time you get a new test to pass, get latest, run all unit tests, and check in. Early and often integration prevents merge problems and allows for increased collaboration.

5) No developer branches. Please don't have a branch for each developer. The merges become a nightmare and it prevents people from collaborating effectively. Plus the current code-base is not readily acceptable until all the developer branches are merged. Really...it's not a good idea.

6) Have refactoring branches. Ok, that 2% of new development that is not done in trunk is done here. Do major development that may destabilize the system on a refactoring or feature branch.

7) Tag when you branch and tag when you merge. All merges should be done from tag to tag, this makes it much easier to keep it straight when you need to update one branch with code from another.

8) Branch for releases. That way you can go back and fix bugs.

For projects that have many branches (and thus many tags) I advocate extending the repository structure like so:

/repository/branches/development
*This is where the feature/refactoring branches go

/repository/branches/QA
* For interim releases or hotfixes

/repository/branches/releases
* For end-of-iteration releases

/repository/tags/branch_name
* Put all tags in a subdirectory according to the branch they were tagged from, this makes it easier to identify for merges

/repository/trunk