Key Takeaways
1. Finding and keeping great developers requires active recruitment and a specific environment.
The great software developers, indeed, the best people in every field, are quite simply never on the market.
Recruitment is active. Since top developers are rarely looking for jobs on public boards, companies must proactively seek them out. This involves going to relevant conferences, leveraging internships to identify talent early, and building a community around the company or its products to attract like-minded individuals. Avoid relying solely on large, general job sites which yield a high volume of unqualified candidates.
Workplace matters. Beyond compensation, great developers seek specific conditions. They value private offices for focus, high-quality tools (monitors, chairs), a social environment with smart, non-jerky colleagues, and significant independence and autonomy in their work. Treating developers with respect and like "stars" is crucial for attracting and retaining them.
Money is secondary. While competitive pay is necessary for fairness, it's often not the primary motivator for top talent. If developers complain about salary, it's often a symptom of dissatisfaction with other aspects of the job, such as lack of respect, poor working conditions, or political dysfunction. A high salary alone won't compensate for a poor environment.
2. Effective management in software relies on identity and shared information, not just commands or incentives.
The goal here is to manage by making people identify with the goals you’re trying to achieve.
Command and Control fails. Military-style management, where leaders bark orders, is ineffective in high-tech teams. Managers often lack the detailed technical information held by individual contributors, leading to poor decisions. This method also alienates smart, autonomous developers who prefer to understand the 'why' behind tasks.
Econ 101 backfires. Managing solely through financial incentives (bonuses for specific metrics) is counterproductive. It replaces intrinsic motivation with weaker extrinsic motivation and encourages people to game the system to optimize for the metric rather than the desired outcome. This approach is an abdication of management's responsibility to build effective systems and train people.
Identity and information empower. The most effective method is Identity Management, fostering a sense of shared purpose and loyalty within the team (like a family). Crucially, managers must share the necessary information (e.g., financial goals, market context) so that individuals can make informed decisions that align with the organization's objectives, even when circumstances change.
3. A strong technical foundation, including "hard" concepts, is crucial for truly capable programmers.
Pointers and recursion require a certain ability to reason, to think in abstractions, and, most importantly, to view a problem at several levels of abstraction simultaneously.
JavaSchools fall short. Universities focusing solely on Java and object-oriented programming may fail to equip students with essential skills. Concepts like pointers (often taught in C) and recursion (functional programming) are traditionally "weed-out" material that require and develop crucial mental agility. Without these, understanding low-level systems like operating systems or high-level abstractions like parallel processing becomes difficult.
Beyond syntax. The value of learning languages like C or Scheme isn't just about knowing those specific languages, but about the way they train the brain. They force programmers to think about memory management, performance, and different levels of abstraction simultaneously. This mental flexibility is vital for designing robust software architecture and tackling complex problems.
Impact on innovation. Lack of exposure to these foundational concepts can hinder innovation. For example, the MapReduce algorithm, fundamental to Google's scalability, draws directly from functional programming concepts (Map and Reduce). Companies whose developers lack this background may struggle to invent or even understand such paradigms.
4. Software development is a craft distinct from computer science, demanding practical skills and clear communication.
Being able to write clearly on technical topics is the difference between being a grunt individual contributor programmer and being a leader.
CS vs. Development. A computer science degree provides theoretical foundations but doesn't automatically teach software development. Practical, programming-intensive courses are essential for gaining real-world coding experience. Many elite universities prioritize theory, leaving practical skills to be learned elsewhere.
The importance of writing. The ability to write and communicate clearly is paramount for programmers. It enables evangelism (like Linus Torvalds with Linux), persuasion within an organization, writing clear specifications and documentation, and collaborating effectively. Programmers who write well gain influence and are more valuable to a business.
In-house pitfalls. Many programming jobs involve "in-house software" for non-software companies. These roles can be unfulfilling because:
- Work is often expedient, not elegant.
- Projects stop once "good enough," limiting polishing.
- Programmers may have low status compared to core business staff.
Product companies, where software is the business, offer more opportunities for pride in craftsmanship and career advancement for developers.
5. Successful software design extends beyond usability to encompass social dynamics and emotional connection.
An application that does something really great that people really want to do can be pathetically unusable, and it will still be a hit.
Usability is necessary, not sufficient. While making software easy to use is important, it's not the only factor for success. Products that solve a strong need or offer compelling features can succeed despite poor usability (e.g., early Napster, text messaging). Conversely, highly usable software that doesn't solve a problem will fail.
Social interface design. For software mediating human-human interaction (social networks, forums), the "social interface" is critical. This involves designing how the software influences user behavior and community dynamics. It's about helping the society succeed, even if it means restricting individual users (e.g., faking spam acceptance).
Emotional appeal matters. Great software often hits "high notes" that resonate emotionally with users. This includes:
- Aesthetics and beauty (e.g., iPod design)
- Humor and personality (e.g., Winamp's website copy)
- Making users feel in control (e.g., iPod scroll wheel feedback)
These elements are often the result of top talent and are difficult for mediocre teams to replicate, creating sustainable competitive advantage.
6. Solving difficult, "gnarly" problems is where real business value and competitive advantage lie.
The market pays for solutions to gnarly problems, not solutions to easy problems.
Value comes from difficulty. Every job has a challenging, unpleasant core problem ("muck"). The ability to solve these difficult problems is what the market rewards ("brass"). Businesses built on solving easy problems face low barriers to entry and intense competition.
Simple isn't always valuable. While simple, easy-to-use applications are appealing, if they don't tackle a significant underlying complexity for the user or business, they may lack deep value. Companies that avoid all "gnarly" aspects (like supporting installable software across diverse environments) may limit their market reach and revenue potential.
Design as a gnarly problem. Creating elegantly designed and highly usable software is itself a difficult challenge. It requires significant talent and effort, making it a source of sustainable competitive advantage that is hard for competitors to copy, even if the surface appears simple. Continuously solving new, difficult problems allows a business to grow and expand its market.
7. Realistic scheduling, informed by data, is vital for managing scope and shipping successful products.
You want to be spending your time on things that get the most bang for the buck. And you can’t figure out how much buck your bang is going to cost without knowing how long it’s going to take.
Developers resist scheduling. Programmers often dislike creating schedules, viewing them as unrealistic or a chore. However, schedules are essential for making informed decisions about feature prioritization and resource allocation. Without them, projects tend to drift and run late.
Evidence-Based Scheduling (EBS). A reliable method involves breaking down work into small tasks (under 16 hours), tracking actual time spent (including interruptions) to calculate individual "velocity" (estimate/actual), and using this historical data in a Monte Carlo simulation to predict a range of possible ship dates with confidence levels. This accounts for individual estimation biases and unpredictable factors.
Schedules force cuts. A key benefit of realistic scheduling is that it highlights when the planned features exceed the available time. This forces necessary feature cuts, ensuring the most valuable features are prioritized and the product ships sooner. Features cut due to schedule pressure are often the least important ones anyway.
8. Refactoring and improving existing code is generally superior to starting over from scratch.
A lesser company, perhaps one run by an executive from the express-package-delivery business, might have decided to scrap the code and start over.
Rewrites are risky. Starting a code base from scratch is often tempting when the existing code is messy or wasn't designed for its current purpose. However, this is usually a mistake, as it discards accumulated knowledge (including bug fixes) and takes vastly longer than estimated, often failing to ship or introducing new problems.
Scrubbing is effective. A better approach is to "scrub" or refactor the existing code base. This involves making small, logical transformations to improve internal structure, readability, and maintainability without adding new features or breaking existing functionality. This process can be done incrementally and predictably.
Benefits of refactoring. Cleaning up code, even line by line, makes it easier to add new features later, reduces the likelihood of introducing new bugs (as you're not rewriting complex logic), and preserves the valuable, hard-won knowledge embedded in the existing code. It's a more efficient and less risky path to a healthier code base.
9. Pricing software involves understanding market dynamics, customer value, and long-term strategy.
The biggest mistake software companies make is charging too little, so they don’t get enough income, and they have to go out of business. An even bigger mistake, yes, even bigger than the biggest mistake, is charging too much, so they don’t get enough customers, and they have to go out of business.
Demand curves slope down. Generally, the higher the price, the fewer customers will buy. The goal is not to maximize units sold, but to maximize
[ERROR: Incomplete response]
Last updated:
Review Summary
More Joel on Software is a collection of blog posts by Joel Spolsky, covering various aspects of software development and business. Readers appreciate Spolsky's wit, insights, and clear writing style. The book offers valuable advice on programming, management, and the software industry. While some content may be dated, many principles remain relevant. Reviewers found the book enjoyable and informative, particularly for those in software development or entrepreneurship. Some critics note repetition from previous works and dated material, but overall, the book is well-received for its practical wisdom and engaging content.
Joel On Software Series
Similar Books









