(C) 2016 Hank Wallace
Are you relatively new to computer programming? A recent graduate? You have a job writing code, but you’re not sure you are moving in the right direction, learning the right skills? This article is for you, and contains advice to help you make the transition from rank amateur to seasoned professional, able to write applications that can stand the test of time.
Look around the computing landscape. We have a proliferation of devices, from PC’s to phones to computers embedded in every device we touch. We have a proliferation of software writers (I’m intentionally not using the term engineer), writing programs for all those devices. What’s the one word you could use to describe the quality of computing today? Mediocre.
As a young person, you probably have not noticed, but the quality of software and the associated devices has been declining steadily. As an aspiring software engineer, I want to clue you in on an opportunity to distinguish yourself from the crowd. Being an excellent software engineer in a sea of mediocrity will quickly let others know who to go to when they need to get the job done right, on time and under budget. That can be you.
But how? I’m going to walk you through some ideas that you’ve probably never considered, but nonetheless can help you avoid the blight of mediocre software engineering, to become an engineer and person of excellence. Ready?
You graduated from a four year college or university with a degree in computer science or something similar, a degree intended to qualify you to work as a programmer. Well, not so fast, because people in industry realize that a degree only qualifies you to set up an email account, and maybe locate your cubicle on the fifth floor. The rest they have to train into you.
There are some realities of education that you have to discover, and I’m going to blurt those out, right here, right now. (If you are a prospective CS student, these things will help you as you work through your college career.)
First, please understand that most of your CS professors have not actually written production programs for a living. They wrote some programs in graduate school, and they have some pet research projects now, but a lot of their current code is written by grad students. These professors have little to qualify them to teach CS apart from the PhD. That’s not necessarily bad, IF you are aware of this fact. Your response is to treat what they say with caution.
Many students fall in with graduate teaching assistants (TAs). These kids have a little more experience than their professors, in some cases, but this amounts to only a tiny amount of real world experience. So you have to take what they say with a grain of salt as well. They may be passionate about their interests and methods, but that does not make those methods good practice in general.
And in the CS department there will be a batch of students who study and eat and sleep together. Some of these kids are sharp and have a lot of potential, but they are susceptible to the fads and silliness that permeates the CS community. Be careful about following them as well.
You have to be your own person, with your own, functioning brain.
The techniques taught in CS departments follow the latest industry fads, because the industries that fund the universities are telling them what skills are being hired. However, there is usually a two to three year delay, so you might not get taught even the latest fads. Watch out for curricula fashioned around buzzwords.
When I was in electrical engineering school, the big hardware buzzword was VLSI (very large scale integrated circuit). Every student project had to mention that buzzword. “My project is electronic dice, implemented as VLSI integrated circuit.” You’ll notice the buzzwords in your group, which today are “agile”, “AI”, “autonomous”, and a bunch of others you can harvest from any CS student’s facebook page.
Here’s a phenomena that will mess with your ability to cope with real world schedules. As a student, you realized that no matter what happened in a semester, after 15 weeks it was over, for better or worse. Thermonuclear armageddon could occur, but at the end of that 15 weeks, the world would reset and you’d start afresh. Problems evaporated. Old pizza boxes magically disappeared from dorm hallways. People graduated. And the sun came out again.
This primes students for a rude awakening in the real world, because there are no such semesters in real life. I’ve worked on some programs and projects for 20 years. Your student experience does not adequately prepare you for the real world software engineering slog, so watch out!
Finally, regarding your education, the CS curriculum teaches you some concepts and how to perhaps write simple computer programs. But the curriculum does not teach you how to think. You have to learn that on your own, and I’ll get to that below.
After you graduate, you get your first programming job, get set up in your dank cubicle in the middle of the fifth floor, get your own stapler and trash can. You are ready to solve all the world’s problems, right? Not so fast. This is actually where your real education begins. Having the right attitude about it is key.
That secret here is that the degree is really only your ticket to further learning. It only made you aware of some basic concepts, and now it’s your job to flesh out those concepts in your mind and make them functional and useful in your work.
One of the most important things a CS grad can do is develop a large tool box. If you have only the tools you learned in college, you are woefully unprepared to solve real problems in the real world. You have to expand that tool box intentionally and continuously. Here are some ways.
Study mathematics. What is computer science, really? It is applied mathematics. “But I hate math.” You’re doing math when you write a computer program, just not the math you hated in high school. Learn to love math. Not just like it, but love it.
An excellent example of this is “The Art of Computer Programming,” by Donald Knuth. He uses mathematics and logic to analyze all sorts of algorithms, and he makes it accessible, easy, and even fun to read. You will have to analyze the algorithms you write, mathematically, to determine their complexity, storage requirements and code size, and this book series is a great way to learn.
Have you ever studied the history of mathematics? There are some very interesting people littering the history of math, and you can learn a lot about math by learning how those people thought about math. Not many of us have the genius of an Euler or Gauss, but many of us have glimmers of genius at just the right time in a project, glimmers that augment the project with great features or cost savings. You can be that glimmer conduit, but only if you fill your mind with the raw material of computer science, math.
Study computer science. There are many techniques that are simply not taught in college because there is not enough time. On every project, I have to expand the limits of my knowledge of CS tools and techniques. I’ll need a method of sorting, or searching, or hashing, something not standard, something with a twist, and I’ll have to search for possible options and create my own. On a recent project I needed to investigate extended methods of error detection and correction, and I learned a lot about the internals of the codes, their structure and efficiency, in order to complete my work. None of this is taught in undergraduate school, and not much in graduate school.
Study statistics. There are many opportunities for a software engineer to use statistics. Say, you have a sales person running into your office every week complaining of an “epidemic” of product issues, all related to your code. How do you address that? He is probably hearing from only one or two customers, and I’ve seen this happen before.
Statistical analysis can help you get a handle on the severity of a problem. Having a percentage incidence figure of an issue can calm a crisis meeting and let the CEO know that he’ll still be able to make his BMW lease payment next month*. Statistics also allow you to track defect rates across software releases and other system changes, such as OS upgrades. For a system with a large population of units, you would be foolish not to track some basic metrics of system health, even if you are not told to do so.
I have worked on one large system where my code is only one of about ten major components of the system. The vendor calls me when problems arise, even if they don’t suspect my code, because I am pretty good at snooping out the source of the issue. They are forever making changes and updates to other parts of the system, and when things go bad it’s a disaster! The size of the fleet is so large that they could easily use statistical measures to determine whether performance has decreased, and likely which component is at fault. But they ignore this tremendous opportunity and depend on vendors to diagnose problems remotely, which is virtually impossible. Much of this statistical analysis could be done in an automated fashion, with little additional labor.
Study numerical methods. More mathematics, I know, but your computer is not an exact computing device, not analog, but digital, and those numerical methods help you compute estimates to real world entities, and compute the expected error.
Study algorithms. Understanding the construction and debug of basic algorithms is very important. Perhaps you need to sort a gargantuan data file. Write it yourself. Then rewrite it so it works well. Perhaps you need to estimate the most likely trajectory implied by a noisy data set. Write a Kalman filter. Perhaps you need to determine optimum control loop parameters for a physical system. Write a PID loop simulation, yourself, and get a feel for how it works.
Hardly anyone writes algorithms any more. If it’s not part of the Java object hierarchy, “we can’t do that here.” Stop copying code off of stackoverflow.com and actually design and code your own algorithm. It’s not going to work (!), but that’s when the fun starts. And when you are finished, you will realize that the algorithm included with the Java object hierarchy is really a poor compromise.
Study your development tools. Like it or not, some source code compiles into efficient object code (or VM byte codes), and some does not. Do you know which is which? It’s easy to write some benchmark code to test the efficiency of your compiler. Test it against various data types. Most smaller machines these days use a native 32-bit data type. Smaller and larger data types will yield varying performance. Do you know which is best for the platform you are using? Examine the compiler’s code output for a few examples and you will find that in some cases the compiler generates almost comical amounts of code. That’s good to know for future projects. Every tool has strengths and weaknesses.
Study the programming model. The programming model is an abstract model of the machine the code is running on. This might be actual hardware, in the case of a small microcontroller, or it might be completely abstract, as in the case of the Java virtual machine. The question is, what’s in that machine? Is it register based, stack based, or some mix? What memory space layout does it have? What power saving features are available? What security restrictions and features are in place?
Way back when, when a programmer wrote a program for a microprocessor, you would see sitting on the desk nearby the hardware manual for that microprocessor. The manual was generally well worn, dog eared, annotated, coffee stained and floppy from many hours of reading. We don’t do that any more, and not just because the manuals are in PDF form. We don’t refer to the manuals because we don’t want to be bothered with all that detail. This is an error.
When you study the programing model of the processor running your code, you are light years ahead of your fellow programmers. Problems will occur, and they will be scratching their latte filled heads, but you will know immediately what they did wrong because you know what the code’s running on.
Write code in multiple languages. You probably wrote code in CS school in one or two languages. That fits the fad model. But not all languages are good for all things. C is good for lower level coding on micros. C# prevents programmers from destroying Windows’ security by using pointers incorrectly (or at all). Java creates an entire environment where most every common programming task is already done for you, even if poorly. Python allows stoners to write code without being bothered by data typing. PHP is good for server side web page generation.
Most languages do a few things right and many things terribly. Learning the languages will help you know which is which and give you some grounds for resistance when your supervisor asks you to write a statistical analysis program in Perl.
Write some assembly language programs. If you want to test your mettle as a programmer, buy a small microcontroller development kit and write some assembly language programs for it. You’ll have to understand the programming model, intimately. You’ll have to pay attention to detail. There’s no assigning a string to an integer and getting a floating point number as a result, as you can in mushy Python, for example. No, every bit must be accounted for. You will have to think.
There’s no safety net when writing code in assembly language. The processor does exactly what you tell it, whatever you assume. Assembly language programming is an exercise in precision thinking. That’s not taught in school, and very few programmers aspire to that level of performance. But you can.
Write code in your spare time. The best young programmers I work with are the ones who love to program, so much so that they spend some of their spare time coding. They are learning and surpassing their weekend kyaking counterparts, and by a large margin. Don’t sacrifice your personal life to computing, but if you do what you love you will love what you do.
And here’s my final bit of advice before we get to the workplace issues: DO NOT depend on open source code! If your’e attitude is that “I can just download a lot of this from sourceforge.com,” then you are of no use to us here. Pick up your Starbucks application on your way out. We have a pile of them in HR.
Computer science school teaches you nothing about working in a production coding environment. Let’s cover some of those things here.
First, in the real world, we make mistakes. If you are not making mistakes, you are playing it safe and not taking risks, and our competitors are likely clobbering us in the marketplace.
The important thing is not to avoid mistakes by playing it safe, but to learn from our mistakes so that we can develop advanced capabilities for future use. Some programmers make the same mistakes over and over. And why not? Management does it!
I had a professor in college who had a big red rubber stamp stating, “SPLLOJL”. It means, “some people live and learn, others just live.” He would stamp our lab reports when we made the same mistakes over and over. I never earned one of those, but a lot of my friends did. It was almost a cause for celebration, though we learned and adapted as a result.
Learn from your mistakes. Shoot, learn from the mistakes of others. How sweet it is to avoid the embarrasment your coworker suffers when he crashes the whole fleet with an untested software update. “I dunno… The relase note on sourceforge said it was stable.”
That brings me to mentoring. There are a lot of older, wiser people in the workplace. Don’t discount their experience. They hired you to do the grunt work and make the stupid errors for them, but you don’t have to be the chump. If you ask for some mentoring assistance, they will likely be impressed and more than willing to help you. I remember a fellow named Denny in my first job who gave me a load of advice regarding some advanced math I was studying. That helped me tremendously, and I almost could not shut him up! Great guy.
Similarly, it helps to watch what others on your team are doing. Look over their shoulders. Watch them code. Examine their code. Ask them why they did things that way. You might learn something. Don’t think you have to code in a bubble.
As projects progress, targets change, specs change, and people come and go. You are going to have to adapt, in real time. You will have to learn new things, in real time. “Say… Jane resigned this morning. We’d like to dump her half baked solution to our complex problem in your lap. Up for it?” What do you say?
You had better be ready to adapt, change, retool, learn and grow. In real time. With a positive attitude.
Another workplace skill you need to develop is knowing when an avenue of investigation is a dead end. Some programmers come up with the most creative potential solutions, with the only problem they are not possible in this space-time continuum. I once inherited a hardware device that made sensitive magnetic measurements. The only problem is that it would not work in the Earth’s magnetic field! I had to tell the customer that this was a dead end. We adjusted directions and made something that worked much better.
Along the lines of statistical measurements, mentioned above, it helps to track your performance, numerically. If you are cranking out code and loading it into a production system, track your part’s defect rate. Track how many lines of debugged, working, shippable code you create every month. Track how long it takes you to fix issues. Work the error rates down toward zero, while increasing your working code output.
In the CS workplace, you will likely be working on a team. This is good and bad. On every team there will be dead wood. There may be young greenhorns, even yourself. And there will be seasoned professionals doing most of the good work.
You have to realize that no matter what tools, techniques and methodologies (sometimes known as mythodologies) are in use, the most valuable team member is the one who is cranking out workable ideas and working, debugged, bulletproof code. It matters not how many initials you have after your name and how much training you have if you cannot solve a real world problem, on your own. Take the advice above and become that person.
As my last word to you, I encourage you to become a whole, rounded person, not just another computer geek writing trash code for trash products. The world has enough of that. Be a problem solver, a generalist, a fad-resistant thinker whose ideas transcend the current pop CS literature. And maybe you can save us from our own technology!
* I hope you are smart enough not to lease a car!