Tuesday, March 10, 2009

Professional Development Ladder

Steve McConnell's company, Construx, uses a very smart approach to professional development within its engineering practice. Here's the whitepaper.

I've been discussing the issue of professional development with friends lately. I was introduced to the idea of parallel career ladders when reading about 3M in Built to Last. Apparently engineers at 3M are not limited in their ability to rise within the company if they choose not to become managers (in many companies, an engineer's only path up the corporate ladder is to become a manager). This gives skilled engineers a path that allows them to further hone their skills without fear of hitting a salary or promotion ceiling.

Construx' approach creates a framework for the engineering ladder. It places high value (and salary) on engineers who become leaders not just within their company, but within their field. The value this sort of engineer can provide to a company is huge, and having a structure in place to acknowledge this value is important. It helps engineers set and achieve goals, and it gives prospective and new employees a clear view into the future their career can lead to.

Here's a question: How high does the ladder really go? Benson suggested that the top engineer in the company is known as "CTO." That works for me. It would be a strong company indeed who had an engineer with a PDL rating of 15 acting as Chief Technology Officer.

Ss.

Thinking About Architecture

I'm finding lots and lots of reasons to think more and more about architecture these days:
  • Architectural reviews coming up at work
  • A new guide to architecture published by the Patterns & Practices folks at Microsoft
  • New projects coming up that are going to require some significant planning
So I'm collecting resources. Here's where I'm looking for guidance, new thinking, and inspiration:
Notice these are all .NET-related. My work is all in .NET these days, so good .NET architectural guidance is important. For those who think there's no difference between strong architectural practices in different technologies, I will just sigh and shake my head, rather than argue the point (at least for now). You're right enough, but I'm looking for the details and subtleties, where specific implementation details diverge in technology-specific ways.

So: If you're reading this and you have more resources you can point me at, please comment. Or email me. Or text or call or tweet or something. I need all the input I can get.

Ss.

Friday, February 20, 2009

Google I/O 2008 Keynote

Spend your next hour watching Marissa Mayer's keynote speech from Google I/O 2008. She introduces a whole lot of different ideas that Google has explored with respect to design as a science, user experience, and building highly scalable systems with a simple interface. She puts forward the concept of "imagination as a muscle," and how Google embraces the concept via brainstorming sessions, 20% time projects, and other ways to "flex" the imagination. I was there for the speech at Google I/O, and watching it again I'm still impressed with the insight she provides.

Ss.


Thursday, February 12, 2009

Scrum for One

I have, over the past few years (and few companies), found myself on a number of "teams" made up of just one member. For those having trouble with the math: yeah, it's just me. There are plenty of books out there that can help software folks manage their teams and their software development process. But I see very little written about the topic of managing the single-person team. So I'll get the party started by providing a handful of tips for developers working solo. I'm an Agile devotee with a preference for Scrum, so I'll illustrate my points using Scrum-specific terminology. But the lessons are the same no matter what your methodology. Adjust accordingly. 

Process Matters
Intra-team communication is an important facet of any software development methodology. On a solo team that communication with other team members is all in your head. But that's no reason to drop the methodologies altogether. In fact, following a strict (albeit modified) process can provide numerous benefits. 

Scrum, for example, creates a framework for setting expectations with your clients. They will know, based on your adoption of Scrum, that they can expect to meet with you before and after each sprint to plan and review your progress. They will know when and where their input is expected. And they will know what sort of reporting to expect.

Scrum also helps you organize the requirements for your project into a manageable task list. It helps you and your clients prioritize your tasks. And it helps you keep track of what you need to do, and when you need to have it done by. These things are all very easy to lose track of when you are working alone.

The daily scrum meeting, though intended to be a discussion amongst team members, remains important on the solo project. Go over the three points you would on a larger team. Put them on a white board or in a notebook. What have you done since yesterday? What will you do today? What is getting in the way of your progress? Now you've got a framework for your day's work.

The Testing Challenge
The biggest challenge for a solo developer is testing your software adequately. The fact is, you can't do it alone. You need outside help. If you're in a solo situation, the decision has already been made: you're the tester. Your software will suffer because of it. So you have to come up with a mitigation strategy. My advice: strengthen your unit testing, and recruit your client's resources for user acceptance testing.

Your unit testing should follow a test-driven-development plan. Write your tests before you write any code. Do not write any code that is not specifically designed to pass your tests. Automate your tests to run with every compilation. Your code should emerge fully tested by the time your development is completed.

User acceptance testing should, in an ideal situation, be the last step in your development process. But without actual testers on the team, you have to get your users involved earlier. Show them your progress during development, so they can provide feedback early. Then recruit anyone who is providing input to the project (graphic designers, writers, etc.) to test your implementation of their input. Recruit random non-experts from your client's organization to try out your software from a a non-technical perspective. Help them help you: provide a test plan that explains what they should cover in their testing, and how they should go about it.

Reporting & Visibility
Scrum proscribes a specific set of reports that you should be providing to your clients: the sprint burndown and product burndown reports. Use these to their fullest extent: publish the reports somewhere where your clients can view them on a daily basis to get updates on your progress. Teach your clients the meaning of the line on the graph: as you make progress, the line slopes down toward the bottom of the graph. I've found that using Microsoft's TFS with the Scrum module installed automates the updates on that report, and provides a trend line that gives my clients an idea of whether or not I'm on target for delivery.

Keep your product and sprint backlogs up-to-date, so they are always useful to your clients. Again, publish them where your clients can get to the latest version. Your clients will appreciate the visibility into your project, and can use the information in those documents for reporting to others within their organization.

Presentation & Planning
Be diligent about your sprint review and sprint planning meetings. Set expectations with your clients about what will happen in each of these meetings. Make sure that your clients understand their roles, and who should be attending these meetings.

Put together a clear presentation for your sprint review. Highlight what you have accomplished. Provide a visual representation of all of your work, even work that has no user interface component. Use Visio to make a diagram if you have to. Give your clients something to see, rather than just something to read about.

Srum On!
Use Scrum (or whatever development methodology you have chosen) to its fullest. Don't be discouraged by the parts of your methodology that don't translate to the single-person team. Most of the components of any good methodology will be just as valid for you working alone as they are for a larger team.

Ss.

Friday, February 6, 2009

The One That Worries Me the Most

As a follow-up to my Top 25 Most Dangerous Programming Errors post, I want to expand on the error that has me the most worried. It turns out it's at the top of the list: Improper Input Validation. The folks who wrote the list call it "the number one killer of healthy software." It's not only highly prevalent, but it's downright easy to defend against. Here are some tips for fighting the good fight.

Understand where your inputs come from
When you're building a web application, your inputs come from four obvious sources:
  • URLs
  • Query Strings
  • Forms
  • Cookies
... and a couple of not-so-obvious ones:
  • Other sites or resources on either your network or the web
  • Your own data
URLs may not be all that obvious to some people. Traditionally URLs are paths to files on a file system, and those paths don't leave much room for malicious activity: if you specify anything other than a known path, you get a 404 error. Fair enough. But with the rise of RESTful development, more sites are using parameterized URLs. You'll see addresses like http://www.flickr.com/sackville (sorry, I haven't posted any photos yet). That username in the URL is input, and it gets processed. There's a SQL query done that uses 'sackville' as a parameter. That's a prime attack point.

Query strings and form inputs should be pretty obvious: they're prime targets for attack.

Cookies, which you may think of as innocuous because they're usually written by your app (rather than by a user), are just as vulnerable as any other input. The reason is simple: anything anywhere in your client's HTTP request (and that includes all of the above) should be suspect. Hackers use custom-built web browsers that emulate your favorite commercial browser, but submit customized requests. They bypass all of your client-side security measures, and submit their own URLs, query strings, form fields, and cookies. We'll get to that "bypass all of your client-side security measures" issue in a moment, and you'll understand why you still need them.

As for your own data and the other resources your app integrates with, the best strategy is to assume that someone has already gotten to those systems, and that their data has been compromised. If it's going into your system, validate it as if it were from an untrusted source. If you're displaying it, encode or escape it (that's another topic altogether).

Define what is OK
Your app doesn't have to accept all forms of input, and in fact it should not. Your responsibility as a developer is to strictly define exactly what sorts of input are acceptable for every single input your app receives. Take a whitelist approach, not a blacklist approach. That means you explicitly define what input is allowed, rather than defining what is not allowed. If a character doesn't make your whitelist, it doesn't make it into the app.

You'll want to define more than one whitelist. Keep one for each type of data your app receives (phone numbers, email addresses, etc.). Err on the side of a more narrow definition of what is OK. If your users complain about a character not being accepted, add that character rather than an entire class of characters. Design your app to limit the variety of input that is accepted: if you are storing US-only phone numbers, there's no reason for them to be letters, and you don't need to store more than 10 digits (save the dashes and parentheses for display).

If your users are choosing from a list your app provides, then there's no reason why you should accept anything that's not on that list. If you can display the list, then you can (and should) validate against it.

Check, check, and then check
Validation should happen in three places: on the client (before submitting input), on the server (as input is received), and at application boundaries (as input is received by one application from another).

As I mentioned above, client-side data validation is not enough. Your app needs to validate -- on the server side -- any data coming in from the client. But that's no reason not to validate on the client side. Client-side validation is your first defense, and can greatly enhance the user experience (by eliminating the round trip to the server just to validate input). There's another huge gain that client-side validation can give you: if you receive invalid input from your client, and catch it on the server using a validation algorithm that is supposed to match the client-side validation exactly, then you have detected an attack on your system. You can respond as you see fit. I recommend something tactical and nuclear.

Server-side validation should start, as stated above, with a validation algorithm that matches the client-side validation. Your business logic may then provide even further validation opportunities, based on the results of some server-side processing.

Any system your server communicates with should perform its own validation of input crossing application boundaries. This includes the app-server-to-DB-server boundary. Your SQL should be validating input, though this is generally limited to data-type checking, data-length checking, and referential integrity checks.

Use Your Tools
Validation is, of course, a common practice, and we have many validation tools at our disposal. I use SQL Server in most of my development, and just using stored procedures for all of my DB interaction gives me a head start -- invalid data types and lengths are automatically rejected. Using foreign key relationships between tables ensures referential integrity. As a .NET developer, I get a vast array of input validation tools built into the framework I'm building with, on the client and server sides. In any modern language you can use regular expressions to build your validation whitelists. Google regular expressions and you'll find some well written, proven regular expressions available for common data types. 

Proper input validation requires some work. It takes some time. But really all we need to do is establish some good habits, build up a set of tools we can use on every project, and make validation into just another thing we always do.

Ss.