The Kollected Kode Vicious

Kode Vicious - @kode_vicious

  Download PDF version of this article PDF

Don't be Typecast as a Software Developer

Dear KV,

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

Dear Looking,

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 society—say, 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 enjoy—but 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 (, as well as the importance of reading papers ( Those articles are both good places to start.


Dear KV,

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

Dear Bound,

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 citizens—or the ruling junta, take your pick—may 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 program—its executing instructions—which 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
Comment on this article in the ACM Digital Library

More related articles:

Nicole Forsgren, Eirini Kalliamvakou, Abi Noda, Michaela Greiler, Brian Houck, Margaret-Anne Storey - DevEx in Action
DevEx (developer experience) is garnering increased attention at many software organizations as leaders seek to optimize software delivery amid the backdrop of fiscal tightening and transformational technologies such as AI. Intuitively, there is acceptance among technical leaders that good developer experience enables more effective software delivery and developer happiness. Yet, at many organizations, proposed initiatives and investments to improve DevEx struggle to get buy-in as business stakeholders question the value proposition of improvements.

João Varajão, António Trigo, Miguel Almeida - Low-code Development Productivity
This article aims to provide new insights on the subject by presenting the results of laboratory experiments carried out with code-based, low-code, and extreme low-code technologies to study differences in productivity. Low-code technologies have clearly shown higher levels of productivity, providing strong arguments for low-code to dominate the software development mainstream in the short/medium term. The article reports the procedure and protocols, results, limitations, and opportunities for future research.

Ivar Jacobson, Alistair Cockburn - Use Cases are Essential
While the software industry is a fast-paced and exciting world in which new tools, technologies, and techniques are constantly being developed to serve business and society, it is also forgetful. In its haste for fast-forward motion, it is subject to the whims of fashion and can forget or ignore proven solutions to some of the eternal problems that it faces. Use cases, first introduced in 1986 and popularized later, are one of those proven solutions.

Jorge A. Navas, Ashish Gehani - OCCAM-v2: Combining Static and Dynamic Analysis for Effective and Efficient Whole-program Specialization
OCCAM-v2 leverages scalable pointer analysis, value analysis, and dynamic analysis to create an effective and efficient tool for specializing LLVM bitcode. The extent of the code-size reduction achieved depends on the specific deployment configuration. Each application that is to be specialized is accompanied by a manifest that specifies concrete arguments that are known a priori, as well as a count of residual arguments that will be provided at runtime. The best case for partial evaluation occurs when the arguments are completely concretely specified. OCCAM-v2 uses a pointer analysis to devirtualize calls, allowing it to eliminate the entire body of functions that are not reachable by any direct calls.

© ACM, Inc. All Rights Reserved.