Table of Contents
- 1. Introduction
- 2. Beginner
- Personal Skills
- Learn to Debug
- How to Debug by Splitting the Problem Space
- How to Remove an Error
- How to Debug Using a Log
- How to Understand Performance Problems
- How to Fix Performance Problems
- How to Optimize Loops
- How to Deal with I/O Expense
- How to Manage Memory
- How to Deal with Intermittent Bugs
- How to Learn Design Skills
- How to Conduct Experiments
- Team Skills
- Why Estimation is Important
- How to Estimate Programming Time
- How to Find Out Information
- How to Utilize People as Information Sources
- How to Document Wisely
- How to Work with Poor Code
- How to Use Source Code Control
- How to Unit Test
- Take Breaks when Stumped
- How to Recognize When to Go Home
- How to Deal with Difficult People
- 3. Intermediate
- 4. Advanced
- Technological Judgment
- Compromising Wisely
- Serving Your Team
- How to Develop Talent
- How to Choose What to Work On
- How to Get the Most From Your Teammates
- How to Divide Problems Up
- How to Handle Boring Tasks
- How to Gather Support for a Project
- How to Grow a System
- How to Communicate Well
- How to Tell People Things They Don't Want to Hear
- How to Deal with Managerial Myths
- How to Deal with Organizational Chaos
- Glossary
- A.
- B. History (As Of February, 2003)
- C. GNU Free Documentation License
- Personal Skills
- Learn to Debug
- How to Debug by Splitting the Problem Space
- How to Remove an Error
- How to Debug Using a Log
- How to Understand Performance Problems
- How to Fix Performance Problems
- How to Optimize Loops
- How to Deal with I/O Expense
- How to Manage Memory
- How to Deal with Intermittent Bugs
- How to Learn Design Skills
- How to Conduct Experiments
- Team Skills
- Why Estimation is Important
- How to Estimate Programming Time
- How to Find Out Information
- How to Utilize People as Information Sources
- How to Document Wisely
- How to Work with Poor Code
- How to Use Source Code Control
- How to Unit Test
- Take Breaks when Stumped
- How to Recognize When to Go Home
- How to Deal with Difficult People
Stress testing is fun.
At first it appears that the purpose of stress testing
is to find out if the system works under a load.
In reality, it is common that the system does work under
a load but fails to work in some way when the load is heavy enough.
I call this hitting the wall or
bonking[1].
There may be some exceptions,
but there is almost always a ‘wall’. The purpose of stress testing is
to figure out where the wall is, and then figure out how to move the
wall further out.
A plan for stress testing should be developed early in the project,
because it often helps to clarify exactly what is expected.
Is two seconds for a web page request a miserable failure or a smashing success?
Is 500 concurrent users enough? That, of course, depends,
but one must know the answer when designing the system
that answers the request.
The stress test needs to model reality well enough to be useful.
It isn't really possible to simulate 500 erratic and
unpredictable humans using a system
concurrently very easily, but one can at least create 500 simulations
and try to model some part of what they might do.
In stress testing, start out with a light load and load the system along
some dimension---such as input rate or input size---until you hit the wall.
If the wall is too close to satisfy your needs, figure out which resource
is the bottleneck (there is usually a dominant one.) Is it memory, processor,
I/O, network bandwidth, or data contention? Then figure out how you can move
the wall. Note that moving the wall, that is, increasing the maximum load the
system can handle, might not help or might actually hurt the
performance of a lightly loaded system. Usually performance under
heavy load is more important than performance under a light load.
You may have to get visibility into several different dimensions to
build up a mental model of it; no single technique is sufficient.
For instance, logging often gives a good idea of the wall-clock time
between two events in the system, but unless carefully constructed,
doesn't give visibility into memory utilization or even data structure size.
Similarly, in a modern system, a number of computers and many software
systems may be cooperating. Particularly when you are hitting the wall
(that is, the performance is non-linear in the size of the input)
these other software systems may be a bottleneck.
Visibility into these systems,
even if only measuring the processor load on all participating machines,
can be very helpful.
Knowing where the wall is is essential not only to moving the wall,
but also to providing predictability so that the business can be managed effectively.
Learn to touch-type. This is an intermediate skill because writing code
is so hard that the speed at which you can type is irrelevant and can't
put much of a dent in the time it takes to write code, no matter how
good you are.
However, by the time you are an intermediate programmer you will probably
spend a lot of time writing natural language to your colleagues and others.
This is a fun test of your commitment;
it takes dedicated time that is not much fun
to learn something like that.
Legend has it that when Michael Tiemann[2]
was at MCC people would stand outside his door to listen
to the hum generated by his keystrokes
which were so rapid as to be indistinguishable.
Non-engineers are smart, but not as grounded in creating
technical things as we are.
We make things.
They sell things and handle things and count things and manage things,
but they are not experts on making things.
They are not as good at working together on teams as engineers are
(there are no doubt exceptions.)[3]
Their social skills are generally as good as or better than
engineers in non-team environments, but their work does
not always demand that they practice the kind of intimate,
precise communication and careful subdivisions of tasks that we do.
Non-engineers may be too eager to please and they may be intimidated by you.
Just like us, they may say ‘yes’ without really meaning it to please you or
because they are a little scared of you, and then not stand behind their words.
Non-programmers can understand technical things but they do not
have the thing that is so hard even for us---technical judgment.
They do understand how technology works,
but they cannot understand why a certain approach would take
three months and another one three days. (After all, programmers
are anecdotally horrible at this kind of estimation as well.)
This represents a great opportunity to synergize with them.
When talking to your team you will, without thinking, use a
sort of shorthand, an abbreviated language that is effective
because you will have much shared experience about technology
in general and your product in particular.
It takes some effort not to use this shorthand with
those that don't have that shared experience,
especially when members of
your own team are present.
This vocabulary create a wall between you and those that
do not share it, and, even worse, wastes their time.
With your team, the basic assumptions and goals do not need to
be restated often, and most conversation focuses on the details.
With outsiders, it must be the other way around.
They may not understand things you take for granted.
Since you take them for granted and don't repeat them,
you can leave a conversation with an outsider thinking
that you understand each other when really there is a large
misunderstanding. You should assume that you will miscommunicate
and watch carefully to find this miscommunication.
Try to get them to summarize or paraphrase what you are saying
to make sure they understand. If you have the opportunity
to meet with them often, spend a little bit of time asking
if you you are communicating effectively, and how you can do it
better. If there is a problem in communication, seek to
alter your own practices before becoming frustrated with theirs.
I love working with non-engineers.
It provides great opportunities to learn and to teach.
You can often lead by example, in terms of the clarity of your communication.
Engineers are trained to bring order out of chaos, to bring clarity
out of confusion, and non-engineers like this about us.
Because we have technical judgment and can usually understand business issues,
we can often find a simple solution to a problem.
Often non-engineers propose solutions that they think will make
it easier on us out of kindness and a desire to do the right thing,
when in fact a much better overall solution exists which can
only be seen by synergizing the outsiders view with your technical judgment.
I personally like Extreme Programming because it addresses this
inefficiency; by marrying the estimation quickly to the idea, it makes
it easier to find the idea that is the best combination of cost and benefit.
- Technological Judgment
- Compromising Wisely
- Serving Your Team
- How to Develop Talent
- How to Choose What to Work On
- How to Get the Most From Your Teammates
- How to Divide Problems Up
- How to Handle Boring Tasks
- How to Gather Support for a Project
- How to Grow a System
- How to Communicate Well
- How to Tell People Things They Don't Want to Hear
- How to Deal with Managerial Myths
- How to Deal with Organizational Chaos
Nietschze exaggerated when he said[Stronger]:
You can often give the stronger team members challenging, but carefully delineated, tasks.
- unk-unk
- boss
The person or entity that gives you tasks. In some cases this may be the public at large.
- printlining
- logging
- divide and conquer
- vapor
- boss
The person who sets your tasks. In some cases,
the user is the boss.- tribe
- low-hanging fruit
- Entrepreneur
- garbage
- busines
- company
- tribe
A group of people you share cultural affinity and loyalty with.- scroll blindness
- wall-clock
Actually time as measured by a clock on a wall, as opposed to CPU time.- bottleneck
- master
- heap allocated
Memory can be said to be heap allocated whenever the mechanism for freeing it is complicated.- garbage
- garbage collector
- memory leak
- Extreme Programming
A style of programming emphasizing communication with the customer and automated testing.- hitting the wall
To run out of a specific resource causing performance to degrade sharply rather than gradually.- speculative programming
Producing a feature before it is really known if that feature will be useful.- information hiding
- object-oriented programming
An programming style emphasizing the the management of state inside objects.- communication languages
A language designed primarily for standardization rather than execution.- boxes and arrows
- lingua franca
- buy vs. build
An adjective describing a choice between spending money for software or writing it your self.- mere work
Work that requires little creativity and entails little risk. Mere work can be estimated easily.- programming notation
- strawman
- wite-paper