Under the Hood

April 22nd, 2005

Imagine that you work in a large and somewhat old-fashioned office building. If you want to send a message to your buddy Joe over at XYZ Corp, this is how it goes. You write out your letter on a piece of paper and put a sticky note on it saying, “Please send to Joe Smith at XYZ Corp,” and hand it to your secretary. She (I said this was an old-fashioned place) puts the letter in an envelope and puts Joe Smith’s name on it. Then she looks up the address for XYZ Corp and writes that on the envelope, along with your return address. Then she hands it off to the guys in the mail room.

What they do is interesting. They look at the address for XYZ Corp and say, “Hmm… that’s out of town. It needs to go to Central.” So they put your envelope inside another envelope and write “Central Post Office” on it.

When it gets to the central post office, they open the outer envelope and read the address on your letter. They say, “Oh, this is going to Chicago,” or wherever. So they put your envelope inside another envelope and write “Central Post Office, Chicago” on it.

Then it gets to the Central Post Office in Chicago. They open up the envelope addressed to them and see the address for XYZ Corp. So they put it in another envelope that just has the 9-digit zip code for the XYZ Corp building on it.

It shows up at XYZ Corp, and the guys in their mail room open up that envelope and see that it’s addressed to Joe Smith. Somebody runs it upstairs to Joe’s secretary, and she opens the envelope and hands Joe your letter. When Joe sends a reply back, it works the same way.

This is how the Internet works.

It’s actually more complicated – there are more middlemen – but that’s fundamentally how it all works. It’s all these little letters (called “packets”) flying around a very, very fast postal system. This is a pretty clear match for email, but it’s also how everything from web pages to streaming video to Voice Over IP works.

When you “go to” a web site, you’re really mailing out a request for a web page. It’s like writing off to a mail-order catalog company. There’s a standard form that defines how you ask for web pages. You fill it out and send it in. You’re sending this little form that says, “I want to see http://www.spuriouspundit.com/index.html”. That request goes out through this metaphorical postal system to the spuriouspundit.com server, and some little toiling minion there xeroxes off another copy of the index.html document and mails it back to you.

Like I said, it’s more complicated than that. How do you keep email and web pages and FTP sites all running on the same machine without tripping over each other? Imagine your office building has a bunch of different departments in it, but they all share the same mail room. Instead of a billing department and a sales department, you’ve got an email department and a web department and an FTP department. The way it works is that they each have different post office box numbers. Whenever a letter comes into your building, the mailroom guys just have to drop it in the right box. One of the rules of this postal system is that the addresses on letters have to have a box number. Furthermore, these box numbers are standardized, so that box 80 is the normal box number for the web department, box 25 is for email, etc. So when you send off your web page request, you know that it’s a web page request, and wherever it’s going, it should be going to box 80.

This is also how you keep your responses straight. Even if you’re the only guy at your company, you could be downloading a couple of mp3s in the background while you’re popping up new browser windows right and left. If all that stuff is landing in the same inbox, you’ll never sort it out. So each time you ask for a web page, you set up a new post office box just for its responses. Your downloads go to boxes 5001 and 5002, and your web pages end up in 5003, 5004, and so on.

Here’s the next wrinkle. Say you send off a request for some big, fat mp3 file that won’t all fit in one envelope. So it gets broken up into a whole bunch of separate letters. Now on top of that, like the real post office, stuff can get lost: Mail trucks get stolen; Some yutz in New Jersey cuts through a long-distance fiber-optic cable with a backhoe. Even if nothing gets lost, there’s no guarantee that everything is going to show up in the order you sent it.

So what do you do? First, you send a letter that effectively says, “Hey, I want to send a whole bunch of letters back and forth with you. Here’s the address you should send all the replies to.” This is where your web browser says, “Connecting to …” in the status bar. Once you’ve got an OK back, you say, “Send me that mp3 file.” You get a whole flood of letters back, numbered “1 of 23″, “2 of 23″ and so on. You count through them and realize that you’re missing number 17, so you send another message saying to re-send it. When you finally have all the letters, you can put them in the right order, open them up, and glom the mp3 file together.

This little procedure we’re going through here is called a Protocol. It’s not part of the postal system itself, but it’s a set of rules that people have agreed on for how to use the postal system. In this case, it’s a way of communicating reliably through a system that isn’t reliable. It’s a layer of communications on top of a layer of communications. It’s very meta.

The internet is built up of layers of these protocols. Like the envelopes inside envelopes, at each stage, you’re only concerned with the outermost layer. You slip on or peel off your envelope, and everything else is just the stuff inside it, be it one layer or many. IP, the Internet Protocol, is the postal system – simple, but not entirely reliable. TCP, the Transmission Control Protocol, provides the reliable, ordered delivery on top of IP. Email (SMTP), the web (HTTP), and others are actually another layer on top of TCP. Essentially, they all define standard forms for different mail-order requests.

Again, it’s even more complicated than that. But for now, lots and lots of little letters zipping back and forth across the world. That’s the way to think of it.

Programming Mindset

April 17th, 2005

So, a friend of mine wants to learn Perl. I figure I can teach her that – Perl is simple. It couldn’t take more than a half-hour to get her up to speed on the basics.

Remember that Picture Hanging essay, about how you aren’t aware of how much you take for granted once you’ve learned something? Yeah. I had no idea how much stuff you have to learn before you can even start programming. You have to understand the environment – what’s going on in a computer – at a much deeper level than most users need. (As the tourist/business traveler/expatriate metaphor rears its head again.)

First, there’s the whole command-line thing. Fortunately, she had that down, ‘cuz I have no idea where I’d even start. Your whole frame of reference has to shift to deal with that. You have to explain about opening and reading from files – that a file is really a sequence of characters (don’t get started on bytes vs. characters). And by the way, the end of a line is actually marked by a character, but you can’t see it. Oh, and pipes: They’re like files, but they don’t really live anywhere. Ummm… yeah.

Then there’s the whole utility program thing: The idea that programs can be little tiny things, that they don’t have to have graphic interfaces – they “talk” to each other.

To most people, an application is something you see and interact with. Even when you do deal with things like the filesystem, it’s mediated by a graphic interface – a metaphor. It’s a good enough metaphor that people aren’t really aware that it is a metaphor, let alone what it’s a metaphor for. To someone whose idea of programs is Word and Excel, the idea of ‘piping’ the output from one program into another just doesn’t make any sense.

OK, so that’s all the environment. Those are the building blocks you have to work with, the walls you live within. Like I said, I got off fairly easy on most of that; I had someone who knew her way around the command line, and had even used grep a few times. The next step was explaining what a program is.

A program is a sequence of instructions, kinda like a recipe. But that doesn’t really capture the issue, because recipes are written for humans. Humans are smart. Computers are very, very stupid. Fast, but stupid.

A computer is like some sort of high-speed, idiot-savant imp. It works very quickly, and it can remember a huge amount of stuff, but it’s fundamentally dumb as a bucket of mud. It can’t think for itself at all. If you want it to do something, you have to explain in minute detail precisely how to do it. You also have to think of all the things that could go wrong and how to deal with them.

Let’s imagine you’ve got this sort of imp, and you want it to go get your groceries. It has to go to the store, find all the stuff on the list, pay for it, and come home. Simple, right? You’re underestimating how stupid your computer imp is. If it knows how to walk, open doors, follow directions, and cross streets without getting run over, it’s only because someone else programmed that much for you.

Let’s assume you’ve got an imp programming language that gives you that much. So you say, “Go to the grocery store, get everything on the list, pay for it, and come home.” First, it goes off and never comes back. You go to the grocery store to see what’s up, and your imp is standing in the freezer section. You told it to get pistachio ice cream. They’re out. The imp is waiting for them to restock.

So now you have to instruct it to try another store. You have to give the imp a list of stores, in addition to the list of groceries. If it gets to the last store without finding everything, it should just come home.

This seems too work, but it always takes your imp a really long time to get groceries. You spend a while following him around (debugging) and discover that he’s going to every store every time, even if he already has everything. Ooops, another fix to make.

You write a bunch more imp code, and send it off. It still never comes home. This time, it’s stuck at the cash register. Spaghetti sauce went up 5 cents from last time, and now your imp doesn’t have enough money, and is stuck in the act of paying. You can just give the imp some extra money, but you’ll always have to deal with the possibility that he won’t have enough. Even though it seems less than ideal, you tell him to just come home if he doesn’t have enough money for everything.

Everything works fine for a while, but eventually, you realize that you haven’t had vanilla ice cream for ages. It’s on the list. You check the stores, and sure enough, they’ve got tons of it. You double-check the list, and it’s on there as “Vannilla”. Okay, maybe you could come up with a system for correcting your typos – one that won’t result in your imp buying a gun when the store is out of gum – but that’s a lot of work. It’s easier for you to just type things right. But if you ever sell (or even give) your imp code to other people, you know there will be an unending stream of complaints about how your stupid imp won’t buy vanilla ice cream.

Programming is all about developing this mindset – learning to think through all of this stuff in advance, figuring out all the ways your imp could screw up anything you tell it to do.

Being Valuable

January 1st, 2005

So, I said earlier that tech people shouldn’t have to negotiate for their salaries. Some of you took this the wrong way. It is not validation for you just sitting in your cube, doing your job, and not paying any attention to the company around you. That’s not good. You should not be completely ignorant of the business side of the house.

Let’s go through the basics here. You are working at a job. Your employers employ you. They pay you a salary. They pay you this salary because you do something that they consider useful. “Useful” generally means “makes money for them”. There may be a fairly indirect path to it, but what you do ultimately brings money in the door. Your usefulness to them is measured by how much money that is. Your perceived usefulness also depends on how visible the connection is between your work and money coming in.

This is why sales people make so much more than programmers. Their work is directly tied to money coming in. The sales guy can say, “I made X in sales this month.” You can argue that because you’re a really good programmer, it’s easy for the sales guys to sell your work. You can argue that the clever work you did six months ago has resulted in a better product, and increased sales now. But that’s very hand-wavey. It’s hard to put dollar figures on that.

There are two things you can do to increase your perceived usefulness. You can publicise your accomplishments, strengthening in the minds of your bosses the connection between your work and money coming in. You can also focus your work on things that make (or save) the company money. Both of these require understanding at least a bit about the business side of things.

Let’s say you’re a sysadmin (because if you aren’t, you probably know one), and you implemented an automated patch management system. Well, that sure made your life easier, and gave you more time for your other work (‘cuz there’s no end of that). And it’s a much more scalable solution, to boot. But how do you sell that to your boss?

Your boss thinks in terms of money. It’s not that he’s inhumane or clueless, it’s just that money is how you measure things. People and equipment are manifestations of money. You are a person, and your time costs them money. Therefore things that save you time save him money. Now the hard part, the maddeningly imprecise part, is figuring out how much.

In this example, you’ll have to have some idea how much time you used to spend patching machines. Guess – you can preface your report with, “According to our estimates…” Say you used to spend 3 hours a week patching machines, it took you a week (40 hours) to set up the system, and now you only have to spend 5 minutes a day on it. So your system “cut patch management staffing requirements by 85%” and will “earn back its initial investment” after about 4 months. Yes, that’s management-speak, but “automated a bunch of stuff” is meaningless to anyone outside of the tech staff. You have to translate it – you have to explain the business impact of what you’re doing.

Note that this cuts both ways. If you only used to spend half an hour a week patching boxes, and it took you a month to set up the system, you’ll have a hell of a time explaining that. Ultimately, you need to learn to do the math up front.

So now what do you do with your new-found spare time? Make yourself useful. First, start learning the bigger picture. Learn more about why you do what you do, and then why your group does what it does. Then start thinking about how that might change, or how they should change. Research new tools and techniques you could use – not just “cool” stuff, but things that will help you do your job better. Learn to apply that business logic.

You can also learn more about the other parts of your company, how and why they do what they do. First off, this is just interesting, like exploring a new world or some weird parallel universe. But there may also be things you can do to help them out. I’m not talking about doing their work for them; I’m talking about situations where you say, “Hey, we could write a tool to do that,” or “Don’t you have a database to track all that?” – situations where a little work by you could save them a lot of time and trouble. You’d be amazed at how much tedious, repetitive crap other people put up with in their work – things that programmers would find some way to automate.

At one job, we had a graphic artist who got stuck doing a monthly update of a web page from a PDF file. It was table after table of financial data. She opened up the PDF file in one window, the HTML in another, and copied it field by field, by hand. Click, drag, CTRL-C, click, CTRL-V. For every single number in every table. The first time she did it, it took her two full days. She griped about it to me, and I said, “that’s insane.” I spent the next day hacking together a couple of utilities and a perl script, and came up with something that parsed the PDF file and generated the web pages. It took about 5 seconds to run, and after that, she just had about 15 minutes of reviewing the pages and making special format tweaks. I made a new best friend that day.

You can earn a lot of good karma that way. It can also help break up the monotony of your regular work. You pick little projects and do them incrementally, on your own terms. You’ve got your “customer” right there, so you can try out all the XP and agile methodology stuff you’ve been reading about. And it can give you an arena for learning new skills or technology. A quick and simple web-based form entry application may be perfect for teaching yourself Ruby On Rails. A report generation tool may be a good way to brush up on your Perl.

When you’re done, make sure everyone knows. Tell your boss, and get him to talk to your new-found friends over in graphic design or accounting or wherever. It’s one thing to toot your own horn, but it another when people outside your department are singing your praises.

Salary Negotiations, Addendum

January 1st, 2005

I just thought of another perverse incentive introduced by salary negotiations – they promote territoriality.

Negotiating 102: Deal from a position of strength. How can an employee get the upper hand? By making themselves essential. It’s not good for the company to have essential employees. Employees get sick. Employees go on vacation (or try to). Employees get pregnant. Employees have children, which is a whole world of conflicting priorities. The company needs to be able to run smoothly while they’re away.

If employees have to bargain, they’ll strengthen their hand by hoarding information. You become an essential employee by not sharing knowledge. You become “the only person who knows …” In tech companies, it’s pretty easy to be the only person who understands a critical piece of code, or knows how to configure specific servers. You generally have to work to not find yourself in that position. But almost anyone can do it. You do it by not writing things down. You don’t document requirements, decisions, client requests, lessons learned, policies and procedures, or the reasons behind them. You keep it all in your head. You prevent it from becoming institutional knowledge.

The people who write everything down, the ones who work up procedures that everyone can follow, write code that everyone can read, and explain all the whys and wherefores of what they do? These are the ones who really create value for the company in terms of institutional knowledge. And if they’ve done a really good job of it, you can replace them at a moment’s notice. Again, the ones who are the most valuable are the ones you can pay the least. But which do you want to encourage?

Bargaining

December 21st, 2004

Once upon a time, I got into a… heated discussion with an unspecified head honcho about salaries. Not mine, mind you. I didn’t think we were paying one of our guys what he was worth, what he could make in the marketplace. Head honcho argued that his job was to keep costs, including salaries, down. If this guy wanted better money, he should bargain harder. At the time, I knew that this was totally wrong-headed, but I couldn’t explain why on the spot. So this argument has festered in the back of my head since then.

Employees, particularly skilled, creative workers (as we programmers flatter ourselves to be) should not have to negotiate against our managers for pay and benefits.

This isn’t some sort of hippie socialist crap – there are two real, clear business reasons for this. The first is that it introduces a perverse incentive. I’m speaking in economic terms – this has nothing to do with anyone’s sex life. Not directly. The second, which is sort of related, is that it’s shitty for morale. If that sounds fuzzy-headed to you, you shouldn’t be managing anyone who’s smarter than a chimp and doing anything more complex than stamping out license plates.

The perverse incentive is simply that salary negotiations set up a system that rewards people for not caring about their jobs. Negotiating 101: The most important factor in any negotiation is the willingness to walk away. You go to buy a house, and that’s the first thing anyone tells you. Don’t fall in love with it. If you aren’t willing to walk away from it, they can take you to the cleaners.

So the people who don’t really care about their jobs, the clock-watchers, the ones who can take it or leave it, who haven’t really bonded with their co-workers, who don’t really believe in the product or take pride in their work? They’re the ones who can walk away. The only thing keeping them there is the cash, so it’s going to cost you more. The ones who aren’t like that, who are emotionally invested in the company? You’re turning that against them. You can’t imagine that’s going to make them happy when they find out.

Now, that part applies to everyone. Technical staff in particular have another disadvantage: The personality traits that make them good at their jobs work against them at the negotiating table. It’s not just through lack of people skills or anything – in order to be good technicians, they have to be bad at selling themselves.

Allow me a brief digression here. Technical staff actually operate in a different universe from the business side of the house. They’re “reality-based” in the disparaging way that our current administration uses the term. Put simply, shit will either work or fail based on the properties of the observable universe. No amount of personal motivation or focus-group work will let a spare, obsolete PC handle a million page hits a day. There’s math there. You can prove things.

On the business side of the house, to an alarming extent, believing things makes them true. If the sales guys are confident and self-assured, if they really believe that they’re great salesmen and they have a great product, people will trust them and buy stuff from them. If the managers believe that the current project is destined for success, and can keep everyone enthusiastic and focused, it’s much more likely to be successful. By contrast, once people start believing it’s doomed, they don’t work as effectively, maybe they leave, and the project fails. (This is that morale thing I mentioned earlier.) It’s all unsettlingly self-referential.

These traits which managers and sales people need to be effective are actually bad for technical folks. Arrogance means you overlook things. You miss subtleties that you’d catch if you were more cautious. Two heads are always better than one; three or four better still. (Okay, yes, there’s a limit to this.) But any technical solution will be better if you can put your ego aside and plunk your idea down in front of some other folks for a good, harsh critical review. Being able to sell them on it by force of personality doesn’t make it better. Being aware of your own failings and limitations makes it better. Being able to let go of your proprietary defensiveness makes it better. Learning to value the people who will poke holes in your designs – the ones who are “not team players” – makes it better. A considerable amount of humility is called for here.

This all makes you pretty easy meat in a salary review.

So, point two: Shitty for morale. Yes, we live in a capitalist economy. Companies compete against each other, often fiercely. But within a company, you need to cooperate, to work together, and to trust each other. Without that, a lot of energy gets wasted on internal politics, turf wars, and jockeying for position.

This is particularly acute for tech workers. Technology is complex and huge. People tend to be experts in a very narrow field. Odds are that you’ll have to cross a lot of boundaries to get anything done. Competition – feuding between fiefdoms – can slow everything to a crawl.

Also, it’s one thing if you’re managing guys who stamp out license plates. You know how to stamp license plates, you can watch them doing it, and you can measure their work by the number of license plates they stamp out. Tech guys, not so much. Much of the time, management has no real idea what these guys are really doing. Even if you could watch them all the time, it might not do you much good. It can be hard or even impossible to distinguish between smart, hard-working guys and slackers. Is the problem really hard, or are they just lazy? Is the system running well because your admin set it up right and maintains it carefully, or is he just lucky so far? Maybe he automated the crap out of everything, and now he just has to sit around, waiting for alarm bells to go off. No way to know. (A hint: If you ever have to choose between the guy who puts in 12-hours days doing everything by hand, and the guy who has a bunch of programs doing his work for him, you want the programmer. Brains scale better than brawn.)

So you have to trust these guys. You’re best bet is to put a bunch of them together and hope they’ll keep an eye on each other. That’s still a lot of trust, and why should they look out for you if you’re not looking out for them? If they think you’re chiseling them on pay, they’re likely to chisel back. It’s pretty easy to goof off and look like you’re working, particularly if you program for fun. At best, they’re not going to put a whole lot of brain power into figuring the best way to do things. The surest sign that this has happened is that the really good ones, the ones with a work ethic and motivation, will leave. They have better things to do than put up with this bullshit.

Don’t go down that road. Keep an eye on the market and pay your folks what they’re worth.