I would like to think that learning more will help me in my everyday job of writing glue and customization code at a systems integrator. But the obvious applicable knowledge is specific to tools and packages that may become obsolete or discontinued even within the lifetime of the project, and in some cases have already reached this destination.
Kode Vicious's temper obviously suffers from having to clean up after the mistakes of his peers. What would he have them learn now so that he can look forward to a graceful and mellow old age?
Looking to Learn
While your concern for my old age is touching, I have to say that the only way I can see being mellow in my old age is with prescription help. I keep thinking that age will actually mellow me, but, alas, as longtime readers of KV can tell you, that does not seem to be happening.
Let's turn now to your question, which I would sum up as, "How do I avoid being typecast as a software developer?" Most people understand typecasting in terms of television or movies, where an actor plays the same role so often that that's the only role the actor is ever offered. Christopher Lee, who until he was cast in the Lord of the Rings trilogy was always the creepy and scary character in what we now think of as campy horror films, comes almost immediately to mind. I'm sure you can think of similar actors and actresses.
Being typecast as a developer is what happens when you keep taking the same jobs and doing the same things that you have always done. Now, of course, it's difficult to get a job doing something that you have no experience with, since most employers ask that you be fluent in whatever particular niche they are working in. I am certainly not encouraging you to lie or pad your resume. All that being said, there are a few things you could do, some of which I've mentioned before, but never in a single reply.
The biggest thing that I encourage all engineers to do is to keep learning about their craft, which does not mean running out to ask your boss to send you to a bunch of conferences or classes. Not that conferences and classes aren't useful, but I've seen far too many people waste time and money going on junkets that have very little to offer.
The easiest thing you can do is to join a professional societysay, ACM. No, I was not required to say that. Happily my editors can rarely find me in person when I'm writing these pieces. They just don't like the kind of places I hide out in. KV's alter ego has been a member of ACM, as well as Usenix and IEEE, since his college days. Student memberships are cheap because all three of these groups have learned the pusher's creed, "First hit is free." Once you're hooked, well, let's just say it's hard to quit.
I always encourage people to subscribe to a journal or two and to read the abstracts of papers in areas they're interested in. Not full papers, because who has the time?! If you read the majority of most abstracts, you'll have an idea of what's going on in your area and you'll also find things that are only tangentially related, which are new avenues to study.
What I think you're most curious about, and it's an important thing to be curious about, is the mix of tools vs. techniques. A tool is something like a specific language or computer program. A technique is more general, and can be applied across any of a set of languages. For example, Python is an OO (object-oriented language)one that I happen to enjoybut I am more interested in how to apply OO techniques in any language rather than focusing only on Python. I often find that many people get wedded to a language, but a language is simply one tool for applying a technique, so study the techniques when you can.
An interest in algorithms is very important as well, because this is where all technique in computer science comes from. At this point most people know that you take a mutex before accessing shared data, but do they know why? Do they know how mutexes work even at a general level? If you understand the technique that underlies a mutex, then you can apply it correctly; if you don't, then you're just following a recipe. Cooks follow recipes; chefs take the recipe and make it their own.
At perhaps the highest level it's important to remain curious about how things work. Treating too many parts of a system as black boxes is a great way to reduce yourself and your work to a simple cog in a large software machine. Take things apart, read code that you're not responsible for, and offer to help on projects that you don't understand.
In the past I've talked about my booklist (http://queue.acm.org/detail.cfm?id=1127862), as well as the importance of reading papers (http://queue.acm.org/detail.cfm?id=1036484). Those articles are both good places to start.
One of the problems I find in building secure software is the number of boundaries that must be crossed and checked between cooperating components. Although computers have certainly gotten faster, that seems to me no reason just to place barriers throughout code and believe that this proliferation makes the code any safer or easier to maintain. Frequently, such barriers seem only to cause delays without providing any real value. Where do you weigh in on this type of debate?
Bound by Barriers
Where do I weigh in? At my doctor's office, alas, where he continues to complain that a steady diet of stress, alcohol, and late-night pizza is leading me to ruin. I think he would like it if he could put a barrier over my mouth, but, then, he would not be alone in that. All boundaries have a cost, in the real world and in software. Perhaps it's easiest for the moment to think about barriers in the real world as an example.
All countries maintain, at some level, their physical borders. They attempt to create narrow areas through which all persons and goods must travel so that their citizensor the ruling junta, take your pickmay be protected from possibly dangerous or harmful products or ideas. Most people have crossed a national border at some time or other in their lives, or they've seen someone do it in a movie. The process is simple to describe: a person is employed to guard the border, and another person wishes to cross the border, usually with some articles that they are carrying, such as extra clothing, a toothbrush, etc. The person crossing the border presents papers to the guard, the guard asks a few questions, and the person is then, usually, free to enter the country. The guard has the right to inspect the person's luggage for contraband, but in practice this is rarely undertaken because the cost is too high to check every person, so people are singled out for inspection on various criteria, most of which are spurious.
With that mental model in place we can now move back to the software world. In our world the traveler is the context of a programits executing instructionswhich wishes to access a service in some part of the system. A very common example from operating systems is a system call, which is a barrier between the kernel and a user program. The reason that we have system calls is that it is dangerous for a piece of code, which could be malicious, or more likely, buggy, to execute directly in the operating-system kernel. If it did, it would have too much access to the system and could cause it to fail or cause other programs to fail.
People have taken this simple model to various extremes. In some systems code is never allowed to cross a boundary in any way. These are message-passing systems, where components send messages to each other in order to get work done. No component of a message-passing system can be corrupted by running code from outside, because an outside thread of execution never enters into the component. Each component reads messages from a queue, computes the answers or takes other action, and returns, sometimes, a result.
The way in which to decide whether or not a boundary is required is to ask yourself two simple, and related, questions:
* What am I trying to protect with this barrier?
* What are the consequences if the barrier fails?
In the case of the operating systems the answers are well understood. We are protecting a common resource with access to the physical hardware from malicious or buggy code; and the consequences of failure are systems that crash, lose data, and are impossible to use.
Boundaries, like any other software construct, are a matter of "just enough, but not too much." The borders of the state of California provide another example from the real world. In the United States you rarely see a border post except where there is an interface to a foreign country or at a seaport or airport. In part, this is for convenience. If every truck carrying goods in the U.S. had to stop at each state, this would add time and cost that trucking companies would not tolerate. California is different. To protect (note the word) its agriculture, it has erected borders with other states in order to inspect vehicles transiting its borders. The state has decided that the cost of not protecting its borders from fruit flies and other agricultural pests is too high to ignore.
In a complex software system there are probably only a few components that need this extra kind of protection, and it's the job of a good engineer to find the right places and put the proper protections in place.
KODE VICIOUS, known to mere mortals as George V. Neville-Neil, works on networking and operating system code for fun and profit. He also teaches courses on various subjects related to programming. His areas of interest are code spelunking, operating systems, and rewriting your bad code (OK, maybe not that last one). He earned his bachelor's degree in computer science at Northeastern University in Boston, Massachusetts, and is a member of ACM, the Usenix Association, and IEEE. He is an avid bicyclist and traveler who currently lives in New York City.
© 2009 ACM 1542-7730 /09/0200 $5.00
Originally published in Queue vol. 7, no. 2—
see this item in the ACM Digital Library
Follow Kode Vicious on Twitter
Have a question for Kode Vicious? E-mail him at email@example.com. If your question appears in his column, we'll send you a rare piece of authentic Queue memorabilia. We edit e-mails for style, length, and clarity.
Ivar Jacobson, Ian Spence, Ed Seidewitz - Industrial Scale Agile - from Craft to Engineering
Essence is instrumental in moving software development toward a true engineering discipline.
Andre Medeiros - Dynamics of Change: Why Reactivity Matters
Tame the dynamics of change by centralizing each concern in its own module.
Brendan Gregg - The Flame Graph
This visualization of software execution is a new necessity for performance profiling and debugging.
Ivar Jacobson, Ian Spence, Brian Kerr - Use-Case 2.0
The Hub of Software Development
(newest first)very good pice of information.