A Proper Mental Attitude
The Tremble Factor
In ancient Rome, so it is said, an architect was required to stand underneath the arch he designed as the scaffolding was removed. If he didn't do his job right, the arch would collapse on top of him. This has been called The Tremble Factor.
Imagine you are on an airplane about to land at a major international airport. As the plane banks into its final approach, you look out the window and see the runway lights that guide the plane to a safe landing. Looking at the runway, you remember that the runway lights are monitored and controlled by a piece of software you wrote. After landing, you proceed to pick up your suitcase from the automated baggage system; a system monitored by software that one of your competitors wrote. Leaving the airport in your automobile you reach over to turn on the air conditioner. This brings back memories of the time you traveled to a customer site where they manufacture compressors for automobiles. On the way home you stop at a railroad crossing while a commuter train passes. The software that monitors the position of the commuter trains is also based on software that you wrote. Once home, you get some snacks and a beverage and sit down in front of the TV to watch the current news. Munching on your snack, you remember that the food company and the beverage company use software you wrote to process and package your food. On the TV is a story about a cold front moving into the eastern United States. The commentator mentions that this will increase the use of natural gas and it reminds you that a major natural gas pipeline company uses software you wrote to monitor the pumping stations.
Although this scenario is hypothetical, every one of these examples is potentially real for me. Software that I have been involved in developing is used in many monitoring and control systems throughout the world. This is The Tremble Factor.
The first principle we have to learn as software developers is that the decisions we make have real-world consequences. The software can have beneficial or adverse affects on those people who purchase and use it. Often we don't even know where, and in what type of systems, the software will be used. Even if you write some small programming library, your software may be bought and used by a company that is creating critical system software. Just because you didn't foresee how the software would be used, doesn't mean you can escape the consequences of what you did. We have to learn to care, and care very deeply, about how we create software. While in the middle of a long software development project it is easy to become overwhelmed by schedules, budgets, design problems, etc., and forget this principle. It is also easy to become obsessed with using the latest software technology, just because it is new, and forget for the moment that we should choose our designs to meet the end users needs, not our own excitement at being on the "cutting edge."
Even more difficult is the challenge of opposing a decision that you think is wrong. People who are not software developers will be motivated by other concerns than you. It is difficult, but necessary, for you to adequately communicate to others what the potential results of their decisions will be. You may not make very many friends this way, and may face difficult career choices at times, but it is imperative that you maintain integrity and stand firm on technical issues. Software is your field of expertise and you should expect others to respect your opinions in that area just as you must respect their opinions in other areas of expertise.
Software technology continuously changes. What was new and unique ten years ago is ancient today. The rate of change may slow down someday, but for now, we must live and work in a field that requires constant learning and development of new skills. This can be very exciting or it can be very frustrating. If you don't have an insatiable curiosity and desire to learn new things, you probably won't make it as a software developer. Even worse, your career may be limited to some mundane task of keeping an ancient system running a little bit longer.
The ability to rapidly assimilate new information goes beyond keeping up with technology changes. You have to be able to quickly research a programming library, an operating system API, or even a large piece of software that you didn't write. Often you will be expected to pick up a programming manual for a system you have never seen and become knowledgeable about it within a few days, or in some cases a few hours.
A software developer must be able to quickly grasp essential knowledge of another, possibly unrelated field. For example, to properly develop specifications for a software project, you need to understand the user's requirements. This may involve learning about the user's business or organization, and how they collect information and what they do with it. Without this attitude, you will never be willing and able to truly understand the user's concerns. However, if you have an insatiable curiosity, it can be very rewarding to learn about some area other than computer software.
An insatiable curiosity is also needed to solve problems. Much of programming involves debugging software that doesn't work properly. This can be a very tedious and frustrating activity, but can also be very rewarding. Many programmers have an innate desire to fix things that don't work or to understand something that doesn't work right to see if they can improve on it. Without this curiosity, you will easily get bogged down in a buggy piece of software to the point you get stuck, give up, or take inappropriate short-cuts just to get it done. Good debugging requires a mental attitude that wants to know why the thing doesn't work first. Only then you can really fix the code properly.
A good software developer must also have a desire to create new things and to find better ways of doing old things. In large part, the rapid advance of software technology is a result of this attitude. Creativity is also needed to find efficient solutions. It is all too easy to just use an existing algorithm, or a simple brute force approach to a program. The best software doesn't just work right; it also works efficiently. But, the efficient solution is not always obvious.
To many people, creativity is mysterious and you often will read comments that you have to "think out of the box," or "go with the flow," etc., with very little practical advice on how to be creative. However, creative thinking ability is not difficult to develop. It can be learned, practiced and improved over time just as with any other mental ability. Here are four basic techniques that can be used to improve creative thinking.
First, check and challenge your assumptions. We all carry around in our mind a model of the world we live in. This model develops as we encounter new things, add them to our experience and memory, and then directs and guides us in making day to day decisions. Unfortunately, this model also results in a set of unspoken, unconscious assumptions about how things work, what is possible and what is not possible. When you encounter a new problem that seems to be impossible to solve first check your assumptions. If you say, "X can't be done" the next thing to say is "WHY?" You will find that you are assuming certain conditions that constrain the outcome. There may be in fact a chain of constraints, each assumed to be true, that leads you to believe the required result is impossible. For each assumed constraint, challenge the assumption. Ask, "What if this assumption isn't true?" and see if the result can be achieved. Then, see if there is a way to remove the constraining assumption.
Second, ignore the practical details. For software developers, this is probably the greatest block to creative thinking. We are experts in the minute details of program logic and it is almost instinctive to jump to discussions of how something can or can't be done. If you want to be creative you have to learn to resist this tendency. Simply ignore the practical details and concentrate on the whole system at an abstract level. Often you will find that most of the assumptions you have to deal with are at the level of implementation. If you ignore the details the assumptions automatically disappear.
Third, broaden your perspective. It is all too common for people to become specialists with only a few areas of knowledge where they feel comfortable. Sometimes the company or client you work for forces this on you. If you are good at something, such as database design, you will be the person always assigned to design the database. This will provide a very rewarding career and a sense of stability and self-worth. It can also lead to a very limited perspective as to what is possible. There is an old joke popular among programmers: "To a man with only a hammer, everything looks like a nail." When you need to be creative, you need as many options as possible. The best way to broaden your perspective is to intentionally seek out writings and speeches by people you disagree with or who have knowledge that you lack. The intent is not to alter your own expertise so much as to increase your knowledge of what is possible. This technique supports the technique of challenging your assumptions. The broader your perspective is the more quickly you can see and correct unwarranted assumptions.
Fourth, suspend judgement on the value of ideas. I have been involved in many brainstorming sessions during my programming career. Over time, I and the people I worked with developed a kind of game that we would use to develop new ideas. First, everyone would get together in the same room and choose a secretary to record on a large writing board everything that we came up with. For the next hour or so, we would shout out ideas for things that we would like to see done. The rule that we followed was that everything we came up with went on the board. No one was allowed to criticize an idea or argue about whether or not it could be done. Once we began to run out of new ideas, we started the second phase. We would attempt to find ideas that were related to each other and rearrange things so associated ideas were put together and duplicates eliminated. Then we would look for dependencies. Often we would find that feature "A" was very difficult, but if we also did feature "B" then we would get both for about the same cost in time and effort. Finally, we would prioritize everything based on the goals set for the future release of the product. In the end, most of what we came up with was discarded, but we also were able to find many new ideas that otherwise might have been missed.
It is a trite, but true saying that "Winners never quit, and quitters never win." Along with everything else, a good software developer must have an indefatigable desire to see things to completion. There often comes a point in development of a piece of software that it seems like it will never work or never be finished. Without persistence, you will never make it to the end.
Beyond just completing the software, you need persistence to find the best design you can. If you quit looking before you find the best solution, the software will not be the best you could have produced. Worse, you will often have to go back and do it over again.
Persistence is also needed to be able to do all the other non-coding tasks involved in software development. Parts of development are very enjoyable while others are tedious. You can't just do the fun parts and skip all the tedious details. Designing a new program is a lot of fun since you get to use your creativity and imagination to its fullest extent. As so often happens, once you get into writing the code, much of the fun is replaced with solving tedious little details, studying operating system libraries, managing a source code repository, updating documents with changes, compiling, etc. You must approach all of these non-coding tasks with the same attention to detail that you put into developing the new design.
Finally, there will always be problems during development. Things you thought would be easy turn out to be difficult and to take more time than you initially thought. At times, unforeseen problems show up very late in the development process. You need to have persistence to keep going, and possibly, to go back to redo something.
Because we as software developers work with programmable machines and get to make those machines do just what we want, it is easy to forget that we are human, the people we work with are human, and the people who will use the system are human. All of us humans have our limits. We can get tired, frustrated, angry, and distracted. A software developer has to be aware of these limits and take them into account.
It helps if a software developer has interests beyond just computers and technology. As technology experts we can become so enamored with the clever things we are doing that we ignore the larger issues of life. Programmers tend to develop an attitude that software technology is the solution to any problem, and that any problem can be reduced to some programmable set of steps. Life is not so simple. There is great diversity of opinions, desires and needs within a society. Always remember that just because we can do something doesn't always mean we should or must do it. Remember The Tremble Factor?