Requirements, people, and monsters (part 3)
The second major system in a development effort is the team. The key distinguishing characteristic of the team is: it is composed of people. People in all of their irrational, emotional, egocentric, and goofy glory.
People are not parts. People are not resources. People do not equate simply to developer hours.
You can’t even get along with the people in your family. How are you ever going to get along with the people on your development team?
For some the answer is a stern “professionalism” that pursues an illusion of the lack of any kind of emotion and requires team members to do the same. Thus sweeping their people-ness under the rug.
For others the solution is a harsh command-and-control environment. “I am the boss, you will do what I say. I don’t care about your personal issues.”
The stereotype of computer guys is that we like “hard science”: numbers, code, engineering. Not soft things like: psychology and people and emotions. Then one day you realize the people around you form the most complex system you will ever have to work with. People are the ultimate computers. People are the most complex software system we will ever deal with. The interactions between people form the most complex systems we will ever see.
But more than that, people are the most significant things we will encounter in our computer careers.
When you realize these things you will be driven out of your computer science hole and into the field of learning about and trying to understand people. Here are some key lessons about people.
People are all the same
Everyone else is just like you. We look at another person. We have a natural tendency to think we are categorically different than they. The stupid manager who has no idea what the code is doing. Our first thought is that they are a different type of person than us. The reality is they are the same type of person as us. The fact that they look stupid to us is more about where the two of us happened to meet. We meet after the manager had gone down his management path and I down my coder path. The difference between us is based on relation to each other, not fundamental differences in the kind of person he is and the kind of person I am. In your future you will go down a similar path and be viewed in a similar light.
But, even if you never become a manager, someone will accuse you of being a stupid manager some day. In the same way that politics works. Someone is a staunch liberal all of their life. Then they say something vaguely pro-business. Suddenly they are labeled a right-wing conservative.
With that in mind, consider:
The idiot programmer who can’t figure out the API. That is you.
The slacker who quits working and leaves you hanging when the deadline arrives. That is you.
The stupid manager who is blind to what is really happening. That is you.
The hotshot kid who thinks he knows everything. That is you.
The inept programmer who created an unmaintainable mess. That is you.
The clueless project manager who is completely. That is you.
Those are all you in the sense that they are people like you who are dealing with their circumstances and trying to get through the day as best they can. Someday you will look like them to someone else.
People are all different
You learn a bit about people and you start to categorize them. People hate to be categorized (at least I do!).
People hate to be labeled.
People hate to be psycho-analyzed.
People hate to feel like someone else has them “figured out”.
It is dehumanizing. Like reducing a person down to a “database administrator”. When you pigeon-hole someone you don’t pay due respect to their people-ness.
We are all unique and must be dealt with as individuals, not just as members of some categories.
The agile movement also brought these issues to the fore.
…we have come to value: Individuals and interactions over processes and tools…
Agile brought us daily meetings where you talk to each other. Agile brought us the idea of developers estimating their own work and signing up for their own tasks. Humanizing ideas.
To summarize then:
- People are the core of the development process
- People are the most complicated and unpredictable system in the process
- People are the most significant things we deal with
- (Oh.. and we all are one)
So go learn about people. Maybe read a classic like Peopleware. Or learn from a master like Jerry Weinberg and books like:
WARNING: These are not your typical computer books. They may take you far outside of your comfort zone.
Comments (0)Use Java thread pool to isolate poorly behaved objects
There is an evil in software systems. Some services are not well behaved. When you call them you may block forever waiting for them to respond. These are toxic services. The really bad aspect of such services is they are infectious.
Imagine you have created a component. It is processing many simultaneous requests from callers. It has many threads running. If your component calls a toxic service in the most obvious way then it will become toxic. The way this happens is that a thread running in your code calls the toxic service. If the toxic service is misbehaving, then your thread blocks forever. A little bit later another one of your threads call the toxic service and it too blocks forever. This will continue until all of your threads are blocked waiting for the toxic service.
If you observe the external behavior of your component at this time you will see that it is toxic just like the toxic service you are using. Sometimes callers get a normal response from your component; sometimes they block forever. You are toxic.
And it gets worse. Consider services offered by your component that don’t use the toxic service. Even these are choked out by all the busy threads blocked on the toxic service. So the failure spreads to include operations that are unrelated to the underlying source of the problem. Even if only 1 out of every 100 operations use the toxic service, the failure will still spread and quickly block all 100 operations.
And it gets worse. Because your component continues to consume resources without bound you will bring down other components running on the same system. The problem also propagates upstream to the calling systems. If the calling components are written in a naive fashion (like your component) then they too will become toxic and continue spreading the love.
This is the way systems die.
So what is the solution? The general solution is to move from synchronous to asynchronous constructs. Invoke the toxic service through asynchronous messaging instead of blocking synchronously on a thread waiting for a response. Calls to the toxic service show up in queues. These queues can be monitored, bounded, and managed.
The problem with the asynchronous messaging solution is that it requires a fairly dramatic change to the design of your code.
Here is a simplified implementation of the asynchronous idea that does not disrupt the design of your code. Allocate a pool of threads for dealing with the toxic resource. Give this pool a safe upper limit. You will never sacrifice more than N threads to the toxic service. This is the foundation of the approach. It provides a safety mechanism to keep the toxicity from spreading without limit.
When your code needs to call the toxic service, instead of calling it directly, it asks one of the brave volunteers from the thread pool to call the toxic service. This is a sacrificial thread that may never return… Set a timeout and wait for a little while to see how the thread fares. If it returns, great! The toxic service is working. If it doesn’t return then give up and tell the caller about the problem.
This leaves the sacrificial thread in the thread pool “hung” waiting for the toxic service. But, since we have an upper bound on the pool size, once we reach the limit we will stop calling the toxic service. If we stop calling it, then it cannot claim any more threads.
This approach leaves your component free to continue servicing requests that don’t require the toxic service. This approach does not consume unlimited system resources so other components on the same computer continue to operate. This approach doesn’t block calling code indefinitely. So the toxic service has been contained!
Now for some code. The Java libraries provide the code needed to implement the strategy. I ran this code on Java 1.6.
Here is an example of a toxic object. Notice how it randomly blocks forever.
import java.util.Random;// A poorly behaved class. public class ToxicService implements Service { private static final int FOREVER = 10000;
private final Random random = new Random();
public void go() throws ServiceException, InterruptedException { if (oneOutOf3()) { // Sometimes it blocks. blockForever(); } else if (oneOutOf3()) { // Sometimes it fails. throw new ServiceException(); } // Sometimes it works! }
void blockForever() throws InterruptedException { // This is what makes this object toxic. Sometimes it // blocks forever // when called. (Ok… not really forever in this // example, but long // enough to see the problem.) try { Thread.sleep(FOREVER); } catch (InterruptedException e) { // Bad code - ignore interruption, just keep running Thread.sleep(FOREVER); } }
boolean oneOutOf3() { return random.nextInt(2) == 0; } }
public interface Service { public void go() throws ServiceException, InterruptedException; }
// Exception thrown by Service. public class ServiceException extends Exception { private static final long serialVersionUID = 1L; }
The following class shows how this ToxicService can be wrapped in a way that will protect the calling code from the bad behavior. This class uses the thread pool tools built into Java to isolate the calls to the toxic object in separate threads. A timeout is used to give up on these calls if they don’t return quickly.
import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit;// A class that "contains" the badness of a ToxicService. public class ContainedService implements Service { // Toxic service that is being contained. final Service service = new ToxicService();
// Thread pool for running toxic calls. ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
public void go() throws ServiceException, InterruptedException { List<Callable<Object>> toRun = new ArrayList<Callable<Object>>(); toRun.add(new Callable<Object>() { public Object call() throws Exception { // Call the service. service.go(); return null; } }); List<Future<Object>> futures = executor.invokeAll(toRun, 1000, TimeUnit.MILLISECONDS); try { // Find out what happened when the service was // called. futures.get(0).get(); } catch (ExecutionException e) { // Propagate the exception that is part of the // interface. if (ServiceException.class.isAssignableFrom(e .getCause().getClass())) { throw (ServiceException) e.getCause(); } throw new RuntimeException(e); } }
public void shutdown() { // Shutdown the thread pool. executor.shutdown(); } }
The ContainedService class can be used like this:
import java.util.concurrent.CancellationException;public class ContainedMain { public static void main(String[] args) throws InterruptedException { ContainedService service = new ContainedService(); for (int i = 0; i < 10; i++) { try { service.go(); System.out.println("success"); } catch (CancellationException e) { System.out.println("timeout"); } catch (ServiceException e) { System.out.println("failed"); } } service.shutdown(); } }
This code works, but it is hand-crafted for the specific object being contained. A better solution would allow us to capture the timeout behavior in a generic form to be applied to arbitrary objects. We can create an InvocationHandler that will generically wrap each call with the timeout behavior.
Notice how the invoke(…) method handles all calls generically and the exception handling deals with all exceptions generically.
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit;// A generic class for timing out operations on poorly // behaved objects. public class TimeoutHandler implements InvocationHandler { // Toxic object. Calls to this object will timeout. private final Object target;
// Thread pool used to call toxic object. ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
public TimeoutHandler(Object target) { this.target = target; }
public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable { List<Callable<Object>> toRun = new ArrayList<Callable<Object>>(); toRun.add(new Callable<Object>() { public Object call() throws Exception { // Call the toxic method. return method.invoke(target, args); } }); List<Future<Object>> futures = executor.invokeAll(toRun, 1000, TimeUnit.MILLISECONDS); try { // Discover result of toxic call. return futures.get(0).get(); } catch (ExecutionException e) { // Unwrap interface specific exceptions. if (InvocationTargetException.class .isAssignableFrom(e.getCause().getClass())) { throw ((InvocationTargetException) e.getCause()) .getCause(); } throw e.getCause(); } }
public void shutdown() { // Clean up thread pool. executor.shutdown(); } }
This InvocationHandler can be used with the Java Proxy mechanism like this:
import java.lang.reflect.Proxy; import java.util.concurrent.CancellationException;public class ProxyMain { public static void main(String[] args) throws InterruptedException { TimeoutHandler timeoutHandler = new TimeoutHandler(new ToxicService()); Service service = (Service) Proxy.newProxyInstance(Thread .currentThread().getContextClassLoader(), new Class[] { Service.class }, timeoutHandler); for (int i = 0; i < 10; i++) { try { service.go(); System.out.println("success"); } catch (CancellationException e) { System.out.println("timeout"); } catch (ServiceException e) { System.out.println("failed"); } } timeoutHandler.shutdown(); } }
Note: This example code uses threads to solve the problem without ever using synchronized, wait(), or notify(). This is important! It means the code has a decent chance of working. The java.util.concurrent package deals with the low-level tricky threading issues for you.
Comments (1)Career advice from Larry Smith
Career advice from Larry Smith:
http://economics.uwaterloo.ca/smithdat/career2.html
“Conduct your career as your business”
Make a plan for yourself. Don’t allow yourself to be simply carried along by the currents of the day.
“You never let your employer have full control of your mind’s agenda. Control of the agenda is control.”
Develop yourself uniquely as a product offering:
“The goal is to be unlike others, to be premium priced, to have distinctive function. And there is only one way to do that… Your ideas make you distinctive.”
Market your offering broadly:
“When employed, you distribute your ideas as broadly as possible…”
“You create a resume of distinctive accomplishment. You do not describe routine duties, letting the job title speak for itself. Rather you describe what exceptional work you did…”Comments (0)
Requirements, people, and monsters (part 2)
Requirements. There is an ever growing, massive pile of requirements. This pile threatens to crush the development team under its weight. The agile movement taught us how to deal with this. Well… before that life taught us how to deal with this… one step at a time. The key to dealing with the pile of requirements is focus.
Planning Game
The planning game is one of the main ways to tame the requirements. First it does this by breaking the pile down into a few piles. Talk with the project sponsor about the requirements. Divide them into three buckets:
items essential for launch
items that are very important
items that can be postponed
The names of these buckets are adjusted to accommodate your current project sponsor. The only important thing is that roughly two-thirds of the requirements are moved into a category of things “not to work on”.
Now apply this process iteratively. Take the remaining pile of “essential” items and continue breaking it down into sets of three buckets until the remaining items is small enough that you feel your sanity restored. This should be a couple of months worth of work.
That is the first key to the planning game, it is a form of triage that allows the team to focus on the essentials. The second aspect is related. Divide the essential elements into a series of very small releases, or iterations. Choose an iteration length of one to two weeks and layout the essential requirements into a series of iterations.
As much as possible have the project sponsor make the decisions about what features go in which iterations. The most important aspect of this part is to have the project sponsor make the changes to the iteration schedule. Give them a quota for how much can be in each iteration and then place the burden on them to arrange the requirements such that there is not too much in any one iteration. This is key because it creates a mechanism for the painful truth to be communicated directly to the sponsor. The truth is that 6 days of work cannot be crammed into 5 days.
If the game is setup correctly the sponsor feels this truth as a direct consequence of their actions, not as some arbitrary bad news that the development team has to tell them. So if the sponsor puts five more requirements into the next iteration then they should see that they need to remove five requirements in order to “make it fit”.
Iterations
Regardless of whether you can make the planning game work, iterations are essential for dealing with the pile. Take a tiny set of features from the pile and focus exclusively on them for a week or two and get them done. That is the essence of surviving and conquering the pile. (If you have a steady stream of support issues then leave room for this in your iteration plans.)
Successfully completing each iteration becomes the defining rhythm of the team. It is the basic stroke of the development engine.
Checklists
Completing iterations provides vital motivation to the team. But we frail humans need to be rewarded more often than once every week or two. We need daily reinforcement. So break the features for an iteration down into smaller steps that can be completed in a few hours. Get these listed for all of the team to see. Now developers can feel the satisfaction of crossing something off the list every day. Crossing items off of the list assures the team that the pile is being conquered.
So the team can survive the crush of the pile by dodging it. Don’t try and carry the weight of all of the requirements. Let the weight rest on the ground. Instead take on small parts of the pile at a time. Always take an amount that you can do and you build a pattern of success day after day, week after week.
Comments (1)Resolio signup
Resolio, our tool for making web resumes, is marching forward towards launch. If you want to be one of the early users then signup to be notified when the service launches.
Comments (0)Requirements, people, and monsters
Software development projects are dominated by three complex systems. First there are the requirements. Not just a few requirements but a massive mountain of requirements:

And it is a dangerous mountain that threatens to come tumbling down as an avalanche:
Crushing the development team. The second system: the team. A group of people. And that is their distinguishing characteristic. They are people. Weird people, creative people, confused people, confusing people, thinking people. That is the source of both their great annoyance and their charm… they are people:
But the people are not alone, they have built an application. They have created a monster:

A monster that requires constant care and feeding. A monster that occasionally goes on rampages threatening life and limb and demanding immediate attention.
That is the dangerous world we live in. A bunch of people under threat of being crushed in an avalanche of requirements and living with a monster. Sounds like fun, eh?
Comments (0)Invest $20 in a RentACoder experiment
If you are a developer you need to experience what it is like to use RentACoder to buy code.
Here is what you do:
Think of a little piece of code you want written. Think of something you would pay $20 for.
Write a one page spec for what you want.
Create an account on RentACoder. This is a bit painful, particularly the part where they validate your financial credentials. But hey, no pain, no gain.
Post the spec on RentACoder, watch the bids come in, pick a likely looking developer, and have them code it for you.
Here is why:
Learn what developers around the world will code for $20.
See what kind of code your competition produces.
See what it is like working with a developer. What does the developer do to help make the effort a success or a failure?
Experience buying software development services. Most coders spend their lives coding, but never get a chance to buy coding services. Experiencing the buying side will help you know how to relate to your buyers better.
If you are serious about your craft of programming it is well worth your time, and money to do a RentACoder experiment. Think of it as a bit of market research. It is guaranteed to open your eyes in some ways.
Give it a try and post a comment back here to let me know what you learn!
Comments (12)3 questions to ask about a programming language
I often come across ad-hoc mini-programming languages. For example, a scripting extension to an app or even something like CSS. When I am introduced to one of these mini-programming language I try to remember the basic elements of programming as described in the Structure and Interpretation of Computer Programs.
Ask the questions:
what are the primitives - what are the basic things the language does?
what are the means of combination - how do you put primitives together?
what are the means of abstraction - how do you create a new primitive from combinations?
Asking these questions leads very quickly to a clear understanding of the power or the limitations of the language. If the language falls short, these questions provide a framework for crisply describing the problem. Moreover, if you are designing such a mini-language (which is a bad idea) then these questions will focus your attention on providing a powerful solution.
Comments (0)10 (or so) tips for learning a new programming language
The first time you hear about some new programming language you have a big, empty, black space in your head. That is your ignorance. The new language is foreign, unknown, a dark void. Learning the language is all about dispelling the darkness in your head and to replace it with a mental model of how the language works. You must cast the light of knowledge on the subject. Here are techniques I use:
Get your hands on it
You may have all sorts of intentions to learn something, but if you don’t have it then it is hard to learn. So first go download the thing you want to learn. You need to be able to hold it in your hand, look at it, and then you can consider actually using it.
Make it do something
This is the classical “hello world” program. The point is to make the language do something, anything. The broader lesson is to choose some initial tasks and make the language do those things. You must start to assert control. You don’t need to write perfect code or even good code at this stage. You simply need to make the system do something. This is the first glimmer of light in the darkness.
Study history
Find out where the language came from. Go back and find the original source material to understand the history of the language. Why was it first created? What kind of problems was it designed to solve? This will help you understand its strengths. What languages influenced its syntax? Does it have a C heritage, a Perl heritage? What accidents of history are responsible for you ever hearing about it (how many languages are created that nobody ever knows about)? Don’t be content to read some distilled version of the history. Look for the original, definitive source that puts the language into context. This is a beginning towards understanding the nature of the darkness.
Browse
Google, flip through books, look at the language source code, visit mailing lists, look at different products. Spend some time just exploring all the different kinds of information there are about the language. At this point you can’t remember much of it, but you will pick up some tidbits, you will start to get a feel for some of the main issues, and you will discover good resources to learn more. Many of these sources will give contradictory and just plain wrong advice, so don’t believe everything you read. This is not so much shedding light on the subject as it is shopping for places to get light.
Read the spec
Find the manual. Don’t just read some magazine articles about how an API works. Find the actual spec or API docs. Find the definitive source that says how it works. This is your map in the darkness. Find the definitive reference materials and keep them close at hand.
Identify the masters
Explore the language community enough to find out who the recognized “masters” of the language are. These could be the people who created the language, but they must be the people who are publicly putting the language to the best use in building real systems. These are the people who define the programming idioms that are characteristic of the language. These are the people who are setting the standard for how to best use the language. Find a guide for the journey into the dark.
Read the writings of the masters
Read what the masters have to say about the language. For .NET this means reading Jeff Richter For C this means Kernighan and Ritchie For Smalltalk you need to read Kent Beck
The main point is to read the good stuff. Don’t content yourself with reading some third-hand story on a miscellaneous web site. Once you learn the language better then you will be in a position to sift through such material, but it can’t be your main source. So by all means browse the web and read all kinds of stuff, but you must look to the experts for your primary education. Follow the master guide into the darkness.
Build something yourself
You can read books and tutorials all day. What the author does will make complete sense. “Of course” you will say… to make blue text appear on the screen that is obviously the right command to use. The problem is that your brain tricks you into saying “of course” to the answers you are given. What you need to do is to try and make the language do something of your own design. So what if you want green text and what if you want it to be tilted at an angle? Well… the book doesn’t say how to do that… now your brain has to engage and actually learn how to make the language do what you want rather than simply assent to what it reads in a book. Now you are traveling through the darkness and gaining first hand experiences to truly understand what the language is all about.
Read a complete description of the system
Find a good reference document that broadly covers everything the language can do. You need to have a complete survey of all of the classes of things that the language provides. For example, if you are learning Java, you need to know not just the basic syntax, but you also need to know that it is possible to integrate native code, to decompile Java code, to run on quite different Java virtual machines, to create a security sandbox, etc. You don’t need to learn all of these things in any kind of detail, but you need to become familiar with the range of possibilities of the language. This is an attempt to establish a general border of the big black void in your mind.
Learn some aspect in great detail
Choose some aspect of the language that you are interested in and become an absolute expert in that topic. Learn everything there is to know about it. Explore every last option, leave no stone left unturned. For example, maybe you take on the issue of threading. Explore every primitive the language offers for thread synchronization, learn all of the mechanics of creating threads, study the idioms that capture the communities sense of “best practice” with threads, learn how threads are implemented on different computer platforms, etc.. This is now a thin beam of light that extends all the way to the bottom of the darkness. There is no remaining mystery around the topic. Nothing hiding in the dark.
Study the work of the masters
Find code written by a master. So not only are you studying what the master has to say about the language, but rather you are learning what the master has said in the language. Read lots and lots of code written by the master. You want to just soak in well written code so it seeps into your thinking and into your style in ways that you are not even aware of. For Lisp this is reading Paul Graham’s On Lisp Here the goal is to learn to navigate the language, not just to get to the other side, but to get there in style, to do good work, to be an expert.
Hang out in the community
Find a community of experts in the language. Often this will mailing list archives or some kind of online forum. Browse through the archives. Spend a few weeks getting the latest messages. This is a way of immersing yourself in the culture of the language. So you will learn how such people think, what kinds of solutions are preferred.
Read the critics
Find the clearest thinking critics of the language and read what they have to say. This is a way to discover some of the hidden pits in the darkness.
Look to the future
Learn where the language is going. You don’t want to simply know how it works today, you want to know how it will work tomorrow. To be an expert you need to be ahead of the general adoption curve. For Java this means learning about upcoming JSR’s or just finding a good resource like Alex’s Java 7 page
So that is all there is to it. If you are trying to learn a new language and you are stuck then look back over this list, find something you haven’t done and go do it.
Of course these are just the starting points. To really know a language you need to build a real system and take it to production… and support it… a few times… over the span of several years… but that is another post.
Comments (8)Marketing for geeks: 3 easy steps!
If you are a techno-geek the word “marketing” brings to mind a smarmy guy telling lies or a high powered executive playing mind games with the masses. Marketing is a subject that you don’t want to touch, you don’t know anything about it and you don’t want to be associated with it. This article is for you. This will give you a definition of marketing that you can claim as your own. After reading this, in casual conversation you can mention your “marketing plan”.
Your marketing plan is all about your story. This is the brief statement of why somebody would want to pay you money. The three step plan is:
Get your story straight
Make your story true
Tell your story
Get your story straight
The first step is to determine what your story is. Some criteria to apply in developing a story.
Truth
True stories typically work better than lies. Of course, there are also intangibles to consider.
Usefulness
The story you tell, the thing you offer, it needs to be useful to somebody. Being an expert video gamer is not much use. Knowing how to generate spam is not much use. Knowing how to design a data warehouse for managers to run their business… useful.
Profitability
Are there people who will pay for your story? Are there enough people who will pay for your story that you can find one of them? Are there places on the web where you can find such people? Can you compete with other providers?
To help answer these questions look at the job postings and rates on RentACoder and oDesk.
Distinctiveness
Don’t come up with the story that you are “generally a really smart coder”. Generally speaking, nobody hires generalists. People hire specific people who can do specific things to solve specific problems. So you need a specific theme for your story: database development, or maybe even database optimization. The more specific the story, the more memorable you will be. But don’t forget the need to be useful.
You may be afraid that a specific story will eliminate you from contention for jobs outside of that specialty. That is true. But it is better to remain a noteworthy contender for some projects rather than be lumped into the indistinguishable pile of people who are not particularly well suited to any job.
Passion
There needs to be some passion in your story. The story needs to be about a topic that you care about. Maybe it won’t inspire others, but at least you need to be interested in it. The reason you need to care is because your passion will saturate what you say in many subtle ways; ways you won’t even be aware of. This passion will attract people to your story.
Richness
Real life things are rich in details and substance. Maybe the richness of your story is the breadth of your different work environments you have been in. Or maybe it comes from the depth of your experience.
There are other ways to enrich your story. Maybe there is a personal detail that you can weave into your story, not as a centerpiece, but as a highlight. Consider Microsoft. Part of their overall marketing is the tale of the Bill and Melinda Gates Foundation. The fact that Bill is generous is not a central aspect of deciding to buy a Microsoft product, but it does add a touch of flavor to the overall story.
Don’t go overboard with this idea. Most people don’t have a really interesting personal story to mix in. On average it seems that most people are about average. But maybe you do have something to share, maybe you were bored and spent a summer cycling across the country and you can weave this into your story.
Arc
Your story needs an arc. This is a thread that is played out through all the parts of the tale. These are the stories that are told across the episodes in 24 or many of the other soap-opera like shows from the latest television fad.
For example, if you are a development manager the the arc may be one of steady growth in software development leadership skills. This arc may be told through many small episodes: started working as a developer, led team of three people, project manager of three teams, then head of a software development department. The arc is the story of increasing leadership responsibility across many episodes.
Make your story true
Do things that make your story true. Or more true. Or more completely true. I don’t mean that your original story is a lie. Maybe a key theme of your original story is that you are a unit testing fanatic. That may be true, but it may also be true that you don’t do it very well. It may be true that there are gaps in your experience and understanding. So let’s take that example. What could you do to make the story more true:
- practice doing it a lot so you get better
- contribute to the development of
unit testing framework - explore an area of automated unit testing you don’t have experience with (e.g. web page testing)
- track down the history of the practice to give depth to your understanding
- study a related topic (e.g. learn about James Bach’s Rapid Software Testing
Tell your story
Telling your story is not saying to someone “I am an expert in blah…”, rather it is telling them by making it obviously, visibly true to them. To continue the previous example, you could tell your story about being a unit testing expert by:
- blogging about unit testing
- publishing online videos that demonstrate the practices
- publishing reviews of tools
- building a testing gizmo and making it available
- volunteering to speak at local user groups about the topic
Look back over those lists and imagine a project sponsor looking to hire a developer who was passionate about automated unit testing. When they stumble on your resume or web page it will be obvious to them that you are what they are looking for.
I presented the steps in this order because it is a logical order, but often the first step comes last. Instead of deciding on a story to tell, we look back and in retrospect understand our story. And really they are not distinct steps at all, they are all part of a more complex process. For instance, the very fact of doing something is often the best way of telling people what you do. Similarly we go through cycles of deciding what to do and doing it. Which leads to my final point.
The story you are telling is really just one aspect of your life story. And, for better or worse, you are one of the principal authors of your life story. So not only do you need to look back at what you do and sell that, but also look forward to the story you want to tell and make that story come true.
Comments (0)


















