Development Tips & Tricks

The Joel Test: 12 Steps to Better Code

Complete article here.

  1. Do you use source control?
  2. Can you make a build in one step?
  3. Do you make daily builds?
  4. Do you have a bug database?
  5. Do you fix bugs before writing new code?
  6. Do you have an up-to-date schedule?
  7. Do you have a spec?
  8. Do programmers have quiet working conditions?
  9. Do you use the best tools money can buy?
  10. Do you have testers?
  11. Do new candidates write code during their interview?
  12. Do you do hallway usability testing?

21 Rules of Thumb for Shipping Great Software on Time

by Microsoft's Jim McCarthy (original article here.)

  1. Don’t know what you don’t know.
  2. Get to a known state and stay there.
  3. Remember the triangle (resources (people and money), features and the schedule.)
  4. Don’t go dark.
  5. Don’t go dark.
  6. Beware of a guy in a room.
  7. Never trade a bad date for an equally bad date.
  8. When slipping, don't fall.
  9. Low tech is good.
  10. Design time at design time.
  11. If you build it, it will ship.
  12. Portability is for canoes.
  13. Enrapture the customers.
  14. Remember one thing: Unity.
  15. State your theme.
  16. Vary it.
  17. Balance it.
  18. Evolve it.
  19. Your product should be a hierarchy.
  20. Establish a shared vision.
  21. Get the team into ship mode.

Rule of 126

... or $100 million in revenue with 20% EBIT margins in 6 years", by Jeffrey Crisan and James Nahirny:

Here are our recommendations:

Some ideas...

What do you about cracks?

Some ideas read here and there

Sales vs. subscription

By JT on JoS:

"One of the nicest pieces of software that I currently use is Quickbooks Online.  It's a web application.  I pay a (reasonable) monthly fee to use this application.  The UI is great.  It's marvelously easy to use, even for somone like me with a minimal understanding of accounting.  It's also quite stable - I've seen it crash once since I started using it, and when it happened, Quickbooks contacted me within a matter of hours to apologize for the crash, ensure that no data was lost (it wasn't), and then tell me that I was getting a free month of service - and this was because there was a couple hours of downtime at 2am on a weekend.
What does that have to do with anything?  Here's what one of the QBOE programmers has to say about the matter:
Snippet: "I love my job. Why? I am finally working on a product whose business model supports iterative design practices.... Online Edition customers pay as they go. We do not need to sell them upgrades. They did not plunk down a big up front investment, thus they are free to leave us at any time. We have to be good. We have to listen and respond...."
Unfortunately, customers too frequently seem to balk at this "pay as you go" system, even though it really does encourage quality and can save them money (in my case, 2 years of QBOE is actually cheaper than the Quickbooks products I would need to buy for myself and my employees to get the same functionality, and I would surely end up upgrading in 2 years or less anyway)."

The Causes of Unsustainable Development

From Unsustainable Software Development and its Causes by Kevin Tate

Project Stresses

Project Controls

Exerpts from Joel on Software

Why Do Large IT Projects Fail?

  1. Poor Definition of Project Scope
  2. Lack of Input from End Users
  3. Lack of Upper Management Commitment
  4. Technical Decisions Made by the Wrong People
  5. Delays in Completion
  6. Cost Overruns
  7. Insufficient Testing$402

NIH Syndrom: If it's a core business function -- do it yourself, no matter what.$8

Hire smart people, and give them full responsibility for their domain; Forget Command & Control$17

The hardest part is hiring good programmers. Once you have them, don't just build a better mouse-trap$20

Hire smart people with aptitude (not just skills) who get things done. Make a decision on the spot right after the interview, and back it up to HR in a couple of paragraphs. Better to reject a good candidate than hire a bad candidate. Ask challenging questions like they do during interviews over at Microsoft to check how a person solves a problem, instead of asking questions whose answer can be found easily on the Web in a matter of seconds. Avoid preconceived ideas about the candidate based on their résumé. Don't listen to recruiters or other people who have interviewed that candidate, and compare opinions afterwards.
Before the interview, read the person's résumé, and follow the following plan (to hire a developer):
  1. Introduction: Who I am, and how the interview will work (asking them how they would solve such and such problem). Put the candidate at ease by not sitting across a desk
  2. Question about recent project candidate worked on, their previous job, or the class they liked best during their last semester: If they held a job previously, check for passion, capacity to explain things in a way that a normal person would understand, and able to find solutions to problems
  3. Impossible Question, eg. "How many gas stations are in Los Angeles?"
  4. Various coding tests. Could also ask them to find bugs in a piece of code. Check how efficient their code is, how they lay it out on paper (adding a closing } before actually writing the part, whether they use a naming convention, etc.)
  5. Ask if they are satisfied with that code? Any bug?
  6. Design Question, eg. asking them how to build a house. Check whether they ask questions instead of going for the design right away, look for creativity, and a willingness to go forward
  7. The Challenge: Check how they behave when contradicted (weak or strong?)
  8. Do you have any questions? Use this opportunity to talk about the company. Even if they are a NO HIRE person, they could be a future customer. Pay attention not to ask illegal questions.$24

Keep the manager/employee ratio low to let people own their area, and be promoted. Managers should not be asked to resolve design conflicts, since they should be the person who knows least about it. Avoid Command and Control Management.$31

People don't like making schedules because it's a pain, and nobody believes they're useful. Don't use sophisticated software like MS Project, and keep things simple, eg. use Excel, one sheet per developer. Each feature consists in discrete tasks. The developer in charge should be the one scheduling his part. Tasks should be measured in hours (eg. each task should be from 2 to 16 hours), so as to force developers to pin down the feature and come up with a very precise list of tasks.
When adding a task, put figures in Original Estimate and Current Estimate, and use the Current Estimate the next time a similar task needs to be done. This also lets you determine whether to cut features or let the project slip. Once a task is achieved, the Current Estimate and the Elapsed fields match, and the Remain field is 0. Remind developers to update the Elapsed column and the Current Estimate column every day before they leave for home. The schedule should include time for vacation and holidays. Also include time for QA.
Developers should not work on new code if bugs need fixing. Fixing bugs the same day they were introduced is easier because the code is still fresh in the developer's mind. Besides, since it's impossible to tell how long it will take to fix a bug, it's another reason not to start working on new code until outstanding bugs remain: The less bugs there remains to fix, the more realistic the shipping date. Include buffer time for late feature additions, and tasks that took longer than expected. Do not let managers tell programmers to reduce an estimate; If they still insist, and an Estimate column for the developer, and make the Current Estimate the manager's column; After the task is done, confront the two columns.
Allow time for integration everyone's code, and fixing inconsistencies and conflicts.
Making a schedule also lets you sort features by importance; If the schedule slips, move the easy/fun features to the next release, and have people work on the useful/important features.
Using Excel allows everyone to edit the schedule document in parallel (File | Shared Lists), filter the list so that a developer only sees the tasks he has been assigned (Auto Filter) sorted by priority (Auto Sort), and display remaining hours for each developer for each priority (pivot tables.)$40

Don't treat your employees like they're in kindergarten, especially when it comes to rewarding them for a product shipped in time. Check that your employee evaluation system also takes unusual talents into account.$47

Do not rewrite a new release from scratch (Netscape, Arago/dBase for Windows, Quattro Pro.) Reading code is harder than writing code, so most developers prefer to rewrite code instead of improving legacy code written by someone else. Old code has been tested and fixed, so rewriting it means you lose all this work. Rewriting from scratch takes time that your competitors can use against you.
To improve legacy code, move code carefully, refactor, change interface. The Build One to Throw Away mantra only applies to small, proof-of-concept applications.$51

A user interface is well-designed when the program behaves exactly how the user thought it would.$55

Users expect programs whose UI look similar to also work in a similar way (the "User model), so stick to standard design and keyboard shortcuts. The architecture of a program is called Program Model. A successful UI is has a User Model and Program Model that match. It's much harder to change the User Model than the Program Model. The only way to learn a lot of how users expect your application to work is to perform usability tests. You don't need more than 5 or 6 users for this. The more complex the Program Model, the easier the UI must be to match the User Model.$61

Try to keep the UI clean (eg. Tools | Options showing years of debate between developers on features, etc.) Don't ask users to make a decision if you can avoid it: Only pop up dialog boxes when really necessary, especially when the user is not in a context where he wants to choose among options (eg. open a Help file, and are prompted to minimize DB size, etc.) Design is the art of making choices. Leave good enough alone (customizable tool bars...) When letting users change an option, make it easy to revert to the previous state, or they'll just uninstall and reinstall your software to get back to the original state.
Offering users with lots of options to customize their application is only a good idea only for users with only one computer (ie. a laptop that they use both at work and at home.) Otherwise, they need to go through the customizing step on every computer. Good options are those that just change visual appearance and program features, without changing the way the program itself works.$71

Use good metaphors so that users have a clue on how your program works without having to read the documentation. A badly chosen metaphor is worse than none. Make the UI use "affordance", ie. make it obvious what a widget does (eg. a label should be 2D while a push-button should be 3D, use tabbed dialogs to separate options, etc.)$75

Skimping on frills like free soft drinks is the best way to tell people that you don't care about building an attractive place to work. If you offer very good food at the cafétéria, people will prefer to stay on-site and eat with their colleagues, which increases communication and learning and increases the amount of time spent in the office. Give workers space, quiet, and privacy so that they remain in the "zone" (absolute concentration) as long as possible without being interrupted. Interruptions are very costly because it takes an average of 15mn to get back up to speed.$77

It's easier on your users if the UI of your application matches those of leading applications, eg. Microsoft Office. Do not underestimate details, eg. CTRL-Z should be Undo, double-clicking a word should select it, etc. You can have a pleasing GUI, but don't break the rules.$85

Principles to keep in mind: Users don't read the manual, so make your program easy to use. Users read manuals only when they have no knowledge of the domain to which the application belongs (eg. using an accounting program when you don't know anything about accounting.) Also true of dialog boxes, so keep the wording to a minimum, and only display dialogs when the user is about to do something that they might regret later (eg. closing a document without saving it.)$91

Make it easy to use your application without a mouse, or at least, with less precise devices like track-balls or touchpads: Drop-down lists should drop down as much as screen space allows, and should drop down when clicked on instead of requiring the user to click on the arrow. Use monospace fonts to make text more readable (eg. difference between l and i, rn and m).$107

Don't make users remember things that the computer can remember for them. Provide clues to make it easier to locate things (eg. Open File dialog : Display contents of graphic files instead of just their filename), and performor tasks (eg. auto-completion feature in Excel.) Remember the bell curve, and program for the masses.$109

Use Activity Based Planning to design your application to let users perform a given task: Think from the user perspective instead of the programmer perspective.
In addition, create imaginary users, which different backgrounds and computer skills, and make a list of important tasks they would wish to accomplish, check the user model (how the user will expect to accomplish those activities), build a first draft of the UI and refine it until it fits the user model for each imaginary user, and perform usability tests to double-check.$99

One tester for every 2 programmers (more if the app is complex.) Each developer should work closely with a tester, and having him test private builds. The QA team should not report to development, and the head of QA should have veto right about releasing a build. Excuses not to hire QA:
  • Bugs come from lazy programmers
  • My software is on the web. I can fix bugs in a second
  • My customers will test the software for me
  • Anybody qualified to be a good tester doesn't want to work as a tester
Use testing as a career move up from tech support, allow testers to take programming classes, let them develop automated test suites, keep hiring because of turn-over, hire testers from different backgrounds, hire temps to have your application tested in original ways. Don't hire programmers and force them to do QA for a while after they're hired.$113

Which company to you want to build: One that grows slowly and profitably (Ben & Jerry), or one that grows fast but burns a lot of cash during its first few years (Amazon)? Do you have competitors, or are you a trailblazer? Network effect = the more customers you have, the more you'll get. Lock-in = cost to switch to the competition. Corporate culture is important for Ben & Jerry companies. B&J companies must/can afford to learn from errors, while Amazon companies do not have the time for it. Giving the impression of getting big fast attracts people. B& = nice place to work; Amazon= Get rich quick.$117

If launching a new platform or OS, make sure you provide compatibility with other, popular platforms so as to have a lot of applications available from day one.$122

If moving to a field that has established competition, recognize the fact, and work to lower or eliminate the barriers to entry. The more expensive the switching cost, the less likely customers of the current competition are to switch to your product instead. Don't try to lock in customers until you have close to 100% of the market.$124

People are less likely to buy applications that don't look professional (eg. using the Java coffee cup as the application icon.) Before porting your application to another platform (eg. Windows to Mac), do the math to see if it makes sense financially considering the cost per user. Use portability layers and platform-independent toolkits to lower the cost.$127

To find good programmers, pay the market price. Money is not the number one motivator for most people: Have people working on sthing they consider worthwhile. Considering the amount of time people spend at work, work needs to be rewarding and pleasant.
  1. Make the workplace attractive
  2. Eliminate obstacles: HR should schedule interviews right away, and give an answer on the spot after the interview, handle housing or immigration issues, etc.
  3. Provide benefits  which are more valuable than the money they cost: more vacation time in exchange for lower base salary, catering service, health club membership, etc. Things that cost nothing: give people authority, let them work with smart people, have them work on exciting projects, give them the opportunity of learning new things instead of doing the same old thing$180

12 steps to better code:
  1. Do you use source control?
  2. Can you make a build in one step?
  3. Do you make daily builds?
  4. Do you have a bug database?
  5. Do you fix bugs before writing new code?
  6. Do you have an up-to-date schedule?
  7. Do you have a spec?
  8. Do programmers have quiet working conditions?
  9. Do you use the best tools money can buy?
  10. Do you have testers?
  11. Do new candidates write code during their interview?
  12. Do you do hallway usability testing?

If you score 10 or below, you're in trouble. Run daily builds during lunch so there's time left to fix it if it gets broken. Whoever broke the build is reponsible for fixing it, which is also a good way to teach everyone how to make builds. Minimal bug DB: complete steps to reproduce the bug, expected behavior, observed (buggy) behavior, who it's assigned to, whether it has been fixed or not. In general, the longer you wait before fixing a bug, the costlier (in time and money) it is to fix. Time necessary to fix bugs is hard to guess, but the time needed to write new code can be scheduled more accurately : A schedule that contains lots of bug fixing is much more unreliable. The software should be ready to ship at all times; This is impossible if a lot of bugs need to be fixed.

A schedule is indispensable because some other actions must be planned in advance (trade shows, etc.), and a schedule forces you to decide which features to keep and which to postpone to the next release in case you are running behind.

A spec is important because it's cheaper to change things on paper than it is once it's in code. Quiet working conditions allows for maximum concentration.$192

Developers can be assigned to one of six different levels (9 through 14), depending on experience/seniority/initiative, and can go up or down in level at any time. Compensation consists of salary, annual bonus, benefits, stock options, startup bonus. Salaries are set publicly set for each level; bonus is the same for everyone, and is based on group achievements, not individual achievements. Startup bonus is the only thing that is really individual-specific.$195

Build a professional ladder that recognizes the fact that not all developers want to move on to management. (8) Technical Intern (9-12) Member of Technical Staff (13-15) Fog Creek Fellow. Performance is reviewed every six months to make sure that people belong to the right level for them, and that they belong to the same level as their peers. If you are using the carrot/stick system, reconsider it because it might not be the best system. Give employees constant feedback on the quality of their work. Use heuristics to accumulate evidence and decide on the level to which an engineer belongs best (years of experience, enable, academic experience, strategic role, programming maturity.
Components of compensation:
  • salary, based on level, with adjustments for cost of living, education, extraordinary skills
  • bonus: none, because they're expected instead of earned, too far off in the future, and may promote politics and negative feelings
  • profit sharing: based on the performance of the whole team
  • benefits: given equally to all full-time employees; include six weeks vacation, three weeks training, full medical coverage and 401K retirement plan, free soft drinks, free Internet access from home, flying business class with no week-end away from home, free professional books + subscriptions, ESPP if the company goes public
  • stock options: Early employees should get more; Number of options is level-based; Do not replace lower salaries with stock-options
  • startup bonus: About 10% of the new employee's annual salary; Must be payed back if s/he leaves before 12 months$203

Your company must solve problems, not come up with products for which people have no use, unless they're just for entertainment.$212

Failing to write specs is the single biggest unnecessary risk when taking in a software project. Baring small, one-week projects, building software without a spec means that you will always send more time and create lower quality code. The act of writing a spec forces you to actually design the program. Editing a spec is fast and cheap, and nobody feels bad about this, while programmers don't feel so good about throwing away code that they spent weeks writing and testing. Communication is also a lot easier when done through a spec because everyone just has to read it to understand how the software is supposed to work (dev, QA, marketing, etc.). If you don't have a spec, communication is much more difficult and expensive (QA tests against what the programmers says instead of what the spec says, marketing can't really understand the problems the software is expected to solve, tech writers have a hard time writing manuals because they don't understand how the software works and have to bother developers constantly for answers, etc.) It's also impossible to have a schedule if you don't have a spec. Don't leave debates on design unresolved (Decisions in 10 minutes or less, or the next one is free), especially hard decisions, because otherwise, developers will work on uncontroversial things and leave out important decisions (most likely projects to fail.) Specs should be used even for small things, eg. words used in the e-mail that is sent to users who forgot their password. Send programmers to writing classes so they're no long afraid of the blank page.$216

Two types of specs: Functional specification (how the program works as seen from the user's point of view), and Technical specification (internatl implementation of the program.)
Every spec should have: disclaimer (in case it's still a work-in-progress), one author for each area (if the project is too big for its spec to be handled by a single person), scenarios, nongoals (features that will not be implemented), overview (like a ToC in a book) with pictures to describe the big picture, then go into the details with all the decisions that will have to be made (dont leave unresolved issues lying about), a section for open issues (with possible alternatives), side notes for a specific audience (Notes to developers, to marketing, etc.), update specs frequently so people don't shelf them. The spec is only frozen when the product is code complete. When editing the spec, increase its version number, and use versioning so people can zero in on the changes.$218

Although it brings diminishing marginal return, you can add more smart people to buid a big project and get increased output. Each product should have a program manager, in charge of the design and the specs, with about one program manager for five developers. A program manager is only in charge of coordinating marketing, documentation, testing, etc., and generally keep a big picture of the company.
Don't promote a developer to program manager (different skillset), don't let marketing people be program manager (usually don't grasp technology well enough to design products), and don't have coders report to the program manager (to get the right thing done.)$222

If people don't read specs, customers don't get what they wanted because the product was not developed according to specs. You have to trick people into reading your specs: Be funny (eg. in examples), don't write specs like code (humans don't want to decode things, and need to be motivated; they need the big picture first, and then, fill in the details; the human brain is not random access, and understands things better when they are more common; imagine what you are asking readers to understand in every sentence), write as simply as possible (unsophisticated vocabulary; short sentences; use means to avoid showing one big block of text such as pictures, tables, or screenshots; reread you spec and edit it until everything is super-easy to understand; don't use templates as one size doesn't fit all)$245

Bugs must be logged into a database. Every bug report needs three things: steps to reproduce, what you expected to see, what you saw instead. A new bug is automatically assigned to the lead developer for the project; A bug must be assigned to one person at all times until it is closed; If a bug is considered fixed by a developer, it is reassigned to the person who created the entry originally to double-check and close it.
Tips for bug tracking: reduce the repro steps to their minimum; a bug is closed by the person who reported it; different ways to resolve a bug: fixed, won't fix, postponed, not repro, duplicate, by design; user source control so that every build can be uniquely identified with an ID, to avoid testing a fix on an earlier version; developers must refuse bug reports communicated by any other means than the bug tracking system; if developers don't use the bug tracking system, testers can just add entries in the system and let it email developers; add entries in the system and developers who don't check it eventually will; to get everyone to use the system, use it to add feature requests instead of just bugs; KISS (keep the form to a minimum, or people won't use the system.)$257

Never rewrite your application from scratch: While you're doing this, you don't have the resources to add new features, and can't respond to competitive threats. Old code has been fixed, and rewriting it will require going through the same iterative process all over again. Perform real QA cycles: Do not just upload builds to your FTP server, and expect your customers/beta testers to perform free QA. Do not rewrite widgets to offer cross-platform compatibility; Instead, use a layer that isolates your application from the underlying OS/GUI; Rewriting widgets means that you lose the benefite of any enhancement brought to the native widgets, and your interface is not consistent with what user expect. You must have a schedule, or developers will prefer to spend time doing the easy/fun parts instead of those really important to users$267

Consider writing your own stuff for critical components to avoid being stuck when you bought a product and the company won't fix a major bug. Good reason to go
for open-source. A good architect only uses tools that can be trusted or fixed.$295

Provide developers with the fastest computers to reduce the Edit-Compile-Test loop (along with the Report-Fix-Retest.) Organize daily builds that are automatic, and complete (all versions). Benefits are: Testers get the new version fast; developers get fast feedback in case a change broke the build even on a platform to which they don't have access; it doesn't take long to see if a build breaks because a developer forgot to check in all the files required; marketing and beta users can pick up a recent faily stable version without waiting for the official release; combined with source control, it's easy to find which check-in caused the build to crash; easier to track bugs, by tellings developers in which precise build the bug was seen. Use the fastest computer you have, write a script to check out the entire project every day at a precise hour, and build it in all the required versions (platforms, languages), including the installer programmer and online documentation; Put each new build in its own directory, coded by date. The whole process must be automated to make sure that no special knowledge is needed to create builds. Set your compilers to maximum warning level and have the script stop if the compiler encounters the smallest warning. Stop everything until the build is repaired. The build script should report failures by eemail or a web page. The person who caused the build process to break is in charge of creating builds until the next time it breaks (good incentive to keep the build working and disseminate knowledge on how to create builds.) Builds should be done during lunch, leaving time in the afternoon to repair it in case of a crash. If teams are not located in the same time zone, schedule builds so that a broken one does not keep the other teams don't get stuck.$300

The main part of being a manager is to give people things to do (task allocation, a.k.a. file dumping.) Multitasking is especially costly to programmers because they need to keep in mind a lot of information; It's more efficient to have people concentrate on one task; a good manager should see if he can handle an emergency himself before delegating it to a programmer.$305

If you start a consulting firm, see if it can have a personal voice instead of sounding just like any other company, educate people, remember that consulting doesn't scale (you'll make more money licensing software thanks to its 100% profit on marginal units), but it's important because it enables you to keep in touch with customers and pay for development while you're not making enough to live off the sales of your software.$308

Hard drives are cheap, so bloatware isn't a big deal if it means that companies can provide software earlier. 80% of people use 20% of the features: Problem is, they're not the same features!$320

Watch out for Architecture Astronauts, ie. people who are prone to thinking in such abstract terms that they are unable to actually design and build software, and lose track of the problems the application was supposed to solve in the first place. A great architecture is useless if it doesn't offer great applications.$341

Remember to eat your own dog food$368

Good software takes ten years. Once it has the features people need, leave it alone, and go develop another application. Mistakes to avoid: Getting big too fast, overhyping the product when it's not ready yet (so you need to keep costs low, which ensures that only a few developers are in charge of the architecture), releasing software too fast ("Internet time") or too often, not selling software on a subscription basis (when you run out of features, people no longer upgrade...), not having a schedule$372

Only fix bugs that matter, ie. only those that have an impact on the application. If you have the resources, do fix bugs because they can tarnish the reputation of your product. Capture as many bugs as possible (eg. applet in your application that mails the log file to support), make the most of people calling tech support (bugs, user experience, feature enhancement, etc.), charge the cost of tech support to the relevant business unit (ask support to keep a list of the top ten bugs for each application) but do not charge customers for support (you lose a valuable source of information) or only charge them if the bug is validated (in which case, charge the business unit), figure out how much it costs to fix a bug$382

Things students should learn to become good programmers:
  1. the relational model and modern DBMSs
  2. user interface design and usability
  3. techniques for coding on large teams
  4. software design and writing functional specifications
  5. debugging
  6. Windows and COM programming
  7. sockets programming and common Internet protocols
  8. database-backed web site development
  9. writing! Because great programmers are great communicators.





Online articles