How to be a Programmer
Martin L. Smith writes "Rob Read has posted his magnum opus, "How to be a Programmer: A Short, Comprehensive and Personal Summary" to Samizdat Press where it can be scarfed by the masses. Rob's book is a forty-page tour through the million-and-one things he thinks a programmer ought to know as he sets out into deep water. One of the reasons he posted this was to get some feedback, so tell him what you think. Samizdat Press is maintained by the Colorado School of Mines to provide a distribution point for free (mostly earth-sciences related) texts."
...Simple, just keep doing the stuff they give you. When one tool doesn't work, pickup and learn a better tool. I remember taking on a student job as a programmer, back in 1981. The path has twisted and turned a bit, but I'm still doing it until I find something else I really like ... or win the lottery ;-)
A feeling of having made the same mistake before: Deja Foobar
There is no substitute for experience, but there is something resembling a fast track.
Get paired to a senior programmer/systems engineer
If you have the opportunity to work with a senior on a one-to-one basis, grab it with both hands. There will not be many times when an experienced guy is willing to work with you or coach you, so rejoice when the opportunity presents itself, take it. A colleague of mine asked me which project he should take: a glamorous one where he would be working in a large team with no coaching, or a boring-looking but difficult job, working under one senior programmer. I adviced him to take the latter... which he did, and while he often complained about the job itself, his programming skills improved by leaps and bounds, which made him a senior programmer on the next assignment. I was glad to see he has taken it upon himself to teach in the same manner and spend lots of time with the junior guys.
If construction was anything like programming, an incorrectly fitted lock would bring down the entire building...
I especially like:
There is a lot of room for miscommunication about estimates, as people have a startling tendency to think wishfully that the sentence:
"I estimate it might be possible if I really understand that problem that it is about 50% likely to be completed in 5 weeks if no one bothers us in that time."
really means:
"I promise to have it all done 5 weeks from now."
Heh heh heh...
Another good reference for this type of info is The Pragmatic Programmer. It lays out how to write flexible, dynamic, and adaptable code, as well avoiding traps that a lot of new programmers fall into. It takes the time to explain the "why's" behind a lot of the engineering approaches advanced programmers take. It is definitely aimed at "junior" programmers, though. Usually when we get someone just out of collage, I point them to this book.
Some quotes from the first few paragraphs:
"I confine myself to problems that a programmer is very likely to have to face in her work."
"Even if she is perfect, she is surrounded by..."
Considering that the female to male ratio in this business is something close to 1 to 100 and that some of us can still work many years in the field without ever meeting a female programmer, I found that somewhat amusing. But I guess it gets boring pretty quick, reading he talk about a generic "she" no one will ever meet...
I don't necessarily think debugging is the most important skill for a programmer, so much as that it is the first really hard skill you have to learn. I think one can do a lot with poor design skills and good debugging skills, especially when just starting out...after all, not everyone can create the design. Surely those who find and report bugs in open-source software are doing a very hard and valuable taks.
It looks fairly sensible, but the main problem is that (1) good programmers know these things and (2) bad programmers usually can't or won't learn. This makes the audience pretty narrow, i.e., inexperienced programmers with decent raw skills.
And this bit made me laugh (2.5):
What do you do when you start to run out of low-hanging fruit? Well, you can reach higher, or chop the tree down.
It just seems like a funny metaphor (picture it in your head, chopping down the tree is sort of overkill just to get more fruit :), although I understand what he's getting at.
czth
4 years ago, I (Mechanical Engineer, major in Design Engineering) was involved in a bigger software project: Building a modular simulation system for vehicles, based on a database and a Multi-body code with output to Excel and lots of fancy stuff in between to make it all work. Since the customers and users were the people from our Design Dept, i.e. Engineers, I asumed that they would have thought through all the specs and that we basically just had to start.
Big mistake! Being good and great Design Engineers in the mechanical and electrical domain, regarding software they were as clueless as any Marketing Drone. Whenever we tried to extract specifications, all we got was "make it work like that old APL code we have, but better and more modern and let is calculate/simulate more correct results". Aaaarrrrggggghhh...
Unnecessarily to mention, that only very few actually knew how the old system worked and under what assumptions it was built.
Well, we boxed our way through and today I am the only person in the company that has the total insight (the other 2 left). Unfortunately, we were never given time to properly document the system (of course the code itself is quite well documented but there is more to do than just that). In my naïvité I thought that the Design Dept with their fixation on drawings and Supplier Specs and Purchase Reservations and Engineering Change Notices should understand the value of proper documentation...
A reflection I can now make: Hiring us Design Engineers to make the work instead of professional Software Engineers was probably the only way for the company to get the job done within reasonable time & budget. Non-existent specs, poorly understood assumptions for certain calculations - what a nightmare for any professional software developer!
Excellence: Moderate (mostly affected by comments on your karma)
Yes, it is probably mistitled. I'd rather expand the essay to include other aspects of programming than change the title...but in the short term I'll do that, thank you.
Using the masculine sense for the indefinite article is correct. I don't know about you but all that 'she must do this with her whatever' stuff is quite distracting.
In Soviet Russia, hot grits put YOU down THEIR pants.
Probably true, but I felt as I read the thing that the author did not understand that making the sort of gross generalizations they were making they were falling into the very same same holes that all other pontificators on the subject fall into. The understanding of how we work becomes a very personal thing, it is brash move for the author to suggest that THIS IS HOW IT IS.
Hence the Twaddle, myth, etc.
Hope I didn't disturb anyones sleep.
Better yet,
BELGIUM! MAN! BELGIUM!
The biggest clue that the writer has no clue about computer programming is his statement that 50 hour weeks are typical and 60 hour weeks are his limit. If you are writing code for more than about 2 hours a day, you are writing bad code that is horrible and buggy. I always try to explain what I do to people as very complicated math homework. Noone can actually do math homework for 60 hours a week. It is far too draining.
The majority of most programmers days at work is spent processing ideas in the back of their heads while they do other things (like post on Slashdot). The 2 typical tasks in programming, adding a new small feature to an existing program and debugging a bug are about 100 lines of code and 2 lines of code respectively. These would take in theory half an hour and 2 minutes respectively. But as the old story goes, its knowing which $1 component to replace in the $1,000,000 machine that costs the $10,000. So it is in programming.
Knowing how to integrate the new features and bug fixes without horribly ruining the existing design is the mark of a good programmer. Actually coding the fix or feature once it has been designed (on paper or in your head) is trivial. Overworking yourself leads to bad design and more bugs, which take even more of your overworked self to fix. This escalating behavior leads to burnout as well as the human brain can not spend that much time working on difficult problems every single day.
Anyhow, now that my brain has figured out how it wants to implement the new feature Im working on, while writing this comment, its back to work to toss out my 100 lines of well designed code. If my writing seems confusing or poorly structured, its because my brain was working on code design, not paragragh design.
But to go full circle ... the ones who have a better understanding are the ones who know when to leave some part(s) alone. Picking the battles is what wins the war.
Here's some feedback.
...
... there is even more you can do. Move I/O handling to a seperate thread (more on this in my next comment.)
...)
Re: Divide and Conquer debugging approach
Knowing *where* to split requires less skill than he suggests. While binary-splitting is useful from an algorithmic point of view, in the arena of debugging, there is no reason to be binary. I will typically split the problem many times (8 or more) at each step. This observes the fact that usually the cost of splitting the code is much less than re-running the scenario to test to see which split it makes it past, or fails to run properly.
Neglecting examples in the debugging section is bad. In particular miss-synchronization of multi-threaded applications is an example that should be shown.
Re: 2.6 How to Optimize Loops
Ok, this is a really short list, and it misses the important principle of "caching", and some of the suggestions are wrong, or typically inconsequential.
1. Sometimes floating point can actually be faster than integer code. This is especially true if the code can be completely pipelined. In particular trying to change from floating point to fixed point algorithms in modern CPUs may actually *decrease* performance. The details of this requires a lot more discussion.
2. Inlining will be ineffective if the function routine is too large, or if the procedure prologue/epilogue cost is either low or unremovable.
3. Fold constants together -- you should be more explicit about what you mean here. Certainly sub-expression elimination is a common technique that usually works well (but compilers are pretty good at finding that for you) but in some CPUs like the x86, immediate absolute value operands are practically cost-free. Perhaps he means "hoist" whenever possible? That certain does help.
4. As to moving I/O into a buffer
5. Try not to divide and avoiding expensive casts requires much more detail. The best thing to say here is the understanding these costs requires understanding the underlying machine code that results from these operations. (Floating point division can actually be relatively cheap in the right context, and differentiating between cheap and expensive casts can sometimes be difficult, and require context as well.)
6. Using pointers rather than indicies -- x86's have sophisticated addressing modes wherein there is commonly no difference between these two alternatives.
Re: 2.7 How to Deal with I/O Expense
An important principle to apply is to realize the parallelism via multithreading can substantially assist these problems. For example if some IO is non-negotiable, or non-predictable, then at least it can be blocked, or streamed in a seperate thread. The reasoning behind this is that modern operating systems can yield (i.e., block) program control (i.e., your execution resources) from a slow to respond thread to the faster ones. So you can overlap all your algorithmic work with the delays while waiting for the data.
Re: 2.8 How to Manage Memory
Something should be said about caching versus non-caching. First of all, point out the cached memory can be tens to hundreds of times faster than main memory (in modern CPUs.) Variables on your local stack, and globals that are commonly used in your inner loops, will tend to be cached. However array streaming will tend to de-cache your data.
Running through your streamed data in multiple passes is especially bad, as it will require reading your data into the cache multiple times.
Again much more can be said here.
Re: 2.9 How to Deal with Intermitten Bugs
This is an important topic. Its because it represents the hardest debugging problem. We all run into it sooner or later. Even if it is a hard subject to tackle, it has to be expanded on. Giving examples here are invaluable. You have to show that as hard as it is, it is possible to ferret out such bugs.
Re: 2.10 How to Learn Design Skills.
The biggest thing to explain here, I think, is to just explain that all code can and should have seperate documentation corresponding to it, that is written *before* the actual code is written.
Re: 3.6 How to Work with Poor Code.
Remember that people may be more open, or willing to learn than you think. If you decide you have to recode something for someone, it may be beneficial to be explicit about this and show them the results. But for such a thing to be effective, and to get over any potential ego problems, you have to make sure the rewrite is absolutely, clearly, obviously better (it should be shorter and more easily readable.) Your goal should be to make sure the programmer that is the target of the rewrite, considers the results to be a better approach that is worth emulating themselves. (Give a man a fish
Section 3.7 needs to be tied to the last paragraph of section 2.1. Scribbling over some "pristene" (sp?) code is irrelevant if you can easily recover it (which you can with good source control.)
Re: 3.8 Unit testing -- my experience with this is a bit depressing. Unit tests always start out being a good thing, but over time, they are an extreme PITA to maintain. Unit testing is a good thing for what I consider *totally generic modules*. The reason being that truly generic modules do not evolve over time, while other code invariably does.
Unit testing can only be effective if there in an enforced automated testing mechanism. I.e., a failure causes an automatic and non-negotiable rejection of code checked into the tree. I have found it remarkably difficult to convince people that such a policy is worthwhile. (SGI used to use such a mechanism, and, of course, it worked wonderfully for them.)
Section 3.9 and 2.4 Belong together. How is 3.9 a team skill?
Re: 5.2 How to Manage Third Party Software Risks
In my experience, this is trivial -- rely on track record. Its more indicative than anything else. If the software has already shipped and has a history, then there is no problem. If it has not yet shipped (and you are hoping that it will in time for you to use it), then you are going to get version 1.0 software at best and more likely you are providing a beta test environment for the third party developer. Just put yourself in the shoes of the third party developer. In what way will they maximize the take away from their involvement in a relationship to sell you software? Remember business relationships can tend to dominate technical ones.
Re: 5.4 How to Communicate the Right Amount
In here you write: It costs its duration multiplied by the number of participants. Please underline and boldface this. It amazes me how managers don't understand this.
Re: 6.1 How to Tradeoff Quality Against Development Time
Remember that a good *design* will be resilient against poor code implementations. If good interfaces and abstractions exist throughout the code, then the eventual rewrites will be far more painless. If its hard to write clear code that is hard to fix, consider what it is wrong with the core design that is causing this.
Re: 6.2 How to Manage Software System Dependence
The harps back to a concept I referred to above as *totally generic modules*. These are just libraries that provide useful functionality and can take input without making any non-trivial assumptions, and contains no dependencies whatsoever.
An example of this is the C run time library. A good example that will help make this clear is that the C run time library is able to provide a quicksort implementation without knowing anything about the underlying array it is sorting.
State-less, assumption-free, zero-dependency code is very valuable. Its maintenance and development will be finite in cost, while its utility is on-going. Imagine the cost of rewriting the C library every time you use it.
Impressing this upon programmers will help them recognize the value of reducing dependencies.
Re: 7.2 How to Utilize Embedded Languages
Ony option you seem to have avoided is the possibility of embedding pre-canned languages. The real problem with embedding a language is that useful language design is harder than you might think at first. People's aversion to using/learning it is bad enough, what happens when they uncover a flaw in your language that is fatal to its design? People who design real languages put a lot of work in them, that cannot be trivialized. Whipping up an embedded language is unlikely to yield the most stellar results.
That said, there are currently numerous options for embedded other pre-canned languages. Python, Lua and Ruby come to mind. Before going off on some adventure of trying to design your own language, consider whether or not you are going to be able to do a better job than what you could do by embedding one of these languages. From my personal experience, I can tell you that Lua can be embedded in a few hours, and has probably the smallest learning curve of any language in existence.
I have to agree with this. When reading the essay, I wondered if the author of the essay thinks of himself as a "she"?
To those who posted a negative reply to AbbeyRoad: Political correctness is old and stale. If women are turned off to programming because the "culture" says that they shouldn't program, then that means that women are more inherently influenced by external and superficial social factors than men. To wit: Being a programmer has long been equated with being an anti-social NERD and GEEK. These are not flattering labels at all. Yet we program.
Only recently have nerds become fashionable because of the MONEY factor. Enter the GOLD DIGGERS, women who seek men for their money. Anybody watch "Joe Millionaire" on FOX, in which women are attracted to a dumb guy solely because they think he has mucho money? Similarly , when the feminists begin to ask, "Why aren't there more women doing computer programming?" in the back of their mind is really the money issue.
We who program for a living, and even we who don't make a dime from our programs, program out of sheer joy and love of programming, not because of what society praises or rewards.
Anybody who programs for other reasons is probably not a good programmer, and are pusuing high-tech for "glamour" reasons, in other words, the ability to say, "I make a lot of money" or for their vanity.
Let me ask you: Do you think there are more comic book collectors who are men or women? Do you think the field of comic books should do more to cater to a female audience? By analogy to programmers, most comic book collectors are considered "dorks" or "nerds", and most are male. Lisa Marie Presley (daughter of singer Elvis Presley) and actor Nicholas Cage recently divorced because Presley wanted Cage to get rid of his comic book collection! There is nothing glamorous about comic books, unless there is money involved. Ergo, no feminists are going to complain about gender bias in the choice of titles, the oversized boobs, or the pandering to the testosterone crowd. You don't see rallys or essays about "gender discrimination" in the comic book field. Nobody cares about "reforming" the comic book industry, and elementary and teenage guys are still going to continue collecting them because they are genuinely fascinated by them, and not because society says they should.
Actualy it's a toss up and makes a huge difference on what your building and what you want to be complex. If your writting an application that runs on a single box and that box is pretty much fixed then all you need to be for decent to good achitecture is a software guy. If your building a large system that might require a bank of servers, load ballancing those servers, local network and a wan then you have more "hardware" stuff to deal with and work your designs around. Lets look at something small load ballancing you could do the normal software method of make a single box bigger, the slightly better method of ok we build middleware boxes that take care of the house keeping and can be statefully LBed to the clients with a big honken back end DB server's with there own LB methods, or if it's something that needs to realy scale and you have control over the client end you write a good client application that can perform resilancy and load ballancing in tandem with the server / middleware end.
Programmers dont get hardware bits but it's funny that hardware guys generaly understand a good deal of the programming bits because most hardware is realy software running on a dedicated platform. And for a business it should be all about the TCO and ROI if it's cheaper to maintain and install an enhanced network to support an application then it makes the most sence to do so but in reality most of the time it's cheaper and easier to enhance the applicaion to be more friendly to those resources. Think about how many applications you know move large chunks of data because it was easier to write the VB / C / Flavor of the month to do that work than do it in SQL as part of a stored procedure?
This is right on - the jobs I've been most attracted to are the ones where they asked me the most technical questions. I'm surprised how little of this sort of questioning many people do when hiring. When I'm interviewing people, I try to put them through their paces as much as possible.
I had one engineer help me take apart a vacuum feedthrough, clean it, and put it back together. She jumped right in and did it. I offered her a job on the spot.
It's not wasting time, I'm educating myself.
The grammar fascist agrees.
The basic problem is that there is no unique pronoun to reference objects of undetermined or unknown gender. Any book setting forth rules of grammar will tell you to use the word "he" in those cases. Nearly every work ever written uses this convention, which is why it sounds "weird."
It's training: when we see the word "she," every one of us is used to that pronoun referencing a person with a known gender. Similarly, depending on context, we're used to "he" referencing a person of known or unknown gender. So rather than suggesting a mild anti-sexist stance (which the author is no doubt doing, since he's male), it's doing the following two no-nos:
1) Bringing images of a known-gendered person to mind when the person's gender is in fact not known
2) Causing almost all of us - who are used to the "he" convention - to get distracted trying to rembember that the "she" could also be a "he"
The moral arguments can proceed forever, but those two facts remain. One thing to remember is that they are not necessarily logical when considered in a vacuum, or in the context of gender equality. Consider it in the context of training (from a very, very early age - from when the average human starts understanding words), and it makes sense.
Maybe one of these days we'll introduce a word like "hesh" and it'll all go out the window - after a generation or two.
I got my Linux laptop at System76.
Unfortunately, common sense needs to be taught because it's not as common as people like to think.
I've found in many cases the blame of bad programmers is on two sets of shoulders:
- Management for not hiring enough senior programmers to teach junior ones and for not allowing time to teach junior programmers.
- Senior programmers for not wanting to teach junior programmers because it'll slow them down or they should figure it out for themselves.
I have no control over the first and I try not to be part of the second. From your comments it sounded like you were part of the second problem, I'm sorry if I offended you and that's not the case.
Retired a few years ago. 40 years of programming,
... but "She" ... is this about political correctness or about programming?
managing programmers, architechting large projects,
etc. ad nauseum, and so forth.
1. In PDF? How can I annotate and respond?
2. She? The first female programmer I met was my wife
3. Serious comments:
One can only (in my not so humble opinion) learn to program well by working with Wizards. Do so at every chance you get. Accept less pay and a not-so-good title if you can work with a Wizard.
Become a mentor. By teaching what you think you know, you will learn what you really know. This can sometimes be a thankless task. Do it anyway.
Move around. If you have done speech recognition,
try database design. Do some hard-core math stuff,
then move on to UI design and implementation. Try new things.
You do have your development environment and source code at home, right? You play with it after or perhaps even during the super bowl because finding that "one last bug" is such fun.
Once you become a manager (and you will, if you are good, because leveraging the work of 20 programmers produces more result than you can produce on your own) keep on programming. Don't become a dull knife.
I hate stereotypes. I consider myself to be a very adept programmer, and I don't match the stereotype at all. I'm an ex construction worker/jet mechanic/auto mechanic/tire sorter/furniture mover, I'm a 6 foot tall, 250 pound tatooed guy. I mean, most of the programmers I know don't meet the sterotype of small, glasses, pocket protector, introverted, nerdy, geeky, feeble, poindexter type stereotypes you hear everywhere. I've been married twice and had children by multiple women, hang out with friends, and still have time to program. I think the reason lots of programmers get so good at it is they have had a life like mine, and don't want to go back to it, so their drive to be successful is greater. Nothing like slinging 6000 tires a day at a goodyear factory to get you motivated to do something better. Also, kids can be a great source of inspiration. Any father would want to give his kids better things than I could just four years ago. I loved programming when I did all of those jobs, but thought the prospect would never be open to someone like me to do it professionally, being that I had kids, failed to go straight out of high school, and had too many other responsibilities to handle to do that. But I managed to work a full time job, get sole custody of two of my three children (third wasn't born yet) upon divorce, take care of kids on my own and go to school and make time for them as I did it. I also got remarried and had another, and am still going strong. Some of the best programmers I've met don't meet the stereotype at all, although there are those out there that do.