From time to time I’m toying with the idea to give a lecture to newcomers in the IT industry (systems or software engineers). Here are some of the points that I would include in it:
Software bugs are inevitable. Just accept it. Thinking that you will get any significant piece of code right the first time is statistically wrong. The correct assumption is that bugs will be there, various kinds of bugs. The answer to this problem is the correct development process. The process should include:
- Automated tests – minimize chance of bugs getting into the production environment. There will be bugs not covered by tests. Production environment usually differs in some ways from the testing environment. This means some bugs will make their way to the production environment so monitoring is needed. Automated tests help combat the following problems:
- Slower development because one becomes hesitant to make changes and has to test manually.
- More bugs as manual tests are not as good.
- Bad code as it will less likely be refactored.
- Gradual deployment of new versions.
- Monitoring – detect errors/bugs in running software. Goes well with gradual deployment.
- Metrics – detect performance issues and errors in running code.
- Automated healing / rollback – tricky technique, use it carefully. Example: the system detects that the last deployed version of the application causes increased latency (or error rate) and automatically rolls back to a previous known-good version.
The aim of the correct process is to minimize the number of bugs that reach the production environment and minimize duration and effect of presence of such bugs in production.
Ready-made solution pitfall
You will read articles and blog posts that state that problem P has S as best solution. Your circumstances may seem similar to what other people engage with but in reality they are unique just for your situation. Think twice before deciding that the problem P is exactly the problem you are solving and whether the solution S is applicable and is best for your situation.
Related: see Hypes section below.
Ease vs simplicity confusion
Simple: a line of code that does something very small and specific.
Easy: a line of code that does a lot by calling a framework function causing thousands of lines of code to be executed.
The IT industry is very hype-prone. Companies develop products for the industry. The bigger the budget, the more hype will be created around such product in order to sell or cause adoption. Even when the company provides you with a product that is free, the company may very well still profit in some indirect way so there is still a commercial interest. Remember that such hypes have nothing to do with how good the product is and especially how well it fits as a solution to a specific problem at hand. Note that advertisements usually do not include a “not for” section.
Detecting a product hype: it’s “cool”, it’s all over the news sites and blogs, the impression is that everyone uses it already and you are a laggard which does not understand how cool it is.
Detecting a product you might want to use: your friends that use the product tell you it’s good or it’s the best alternative and/or it matches the criteria you thought of before searching for the product.
Quoting Avishai Ish-Shalom:
Here’s how I recognise hypsters and hyped technology:
“it solves everything! it has no disadvantages!”
Here’s how I recognise experience and serious technology:
“it’s good for X but can also do Y to a degree, but beware of T, Z”
See also: Prove your tool is the right choice
Be a skeptic
When considering doing a task, assume the following (unrelated to each other) aspects:
- Your task will take more time and effort than you estimated.
- The resulting code will make the system much more complex and will be a nightmare to maintain.
- The feature will rarely or never be used. That is often the case.
Professionals usually avoid doing tasks which are “nice to have” and are not really required. Being a skeptic usually has almost no penalty when you are wrong but can save a lot of time and effort when you are right.
- Duplicated code means more maintenance.
- Duplicated code may some day be updated in one place and not the other, causing bugs.
- You will be looked down upon by senior developers as this is a big no-no.
- This rule has rare exceptions, use your judgment. If not sure, don’t duplicate.
Do it. When using any existing code whether it’s a function, program, utility, library or framework – take the time to read the documentation first. Understand the functionality, limitations, architecture. It is a very good investment of your time. You can learn it the hard way after several times when you discover that the particular code is not what you need. Such mismatch usually needs either a work around or picking another library, function or tool.
Pick one style and stick to it. In cases when a project has few styling conventions for some reason, the local convention wins. Example: all files use tabs except the file that you are editing, which uses spaces. In this case use spaces. Inconsistent code style causes higher maintenance costs and developers’ frustration.
System complexity and code complexity
Strive for simplicity. More complex systems:
- Are harder to maintain
- Are harder to add new code to
- Have more bugs
- Have bugs that are harder to find
Complex and complicated are different things. The system or code might need to be complex when solving a complex problem. Complication is an unnecessary byproduct of bad software architecture, bad design or bad implementation. The more professional the programmer is the simpler and cleaner the produced code gets.
Benefits of automation are:
- Avoiding boring repetitive tasks
- Minimizing chances of mistakes (common in manual tasks)
- Describing the task for your future self and others
- Allowing others to do the task easily
- Increased productivity
Here are important defaults the can save you many tears. Deviation from these requires justification.
Knowledge and proficiency
- Big O notation.
- Common data structures and how they are implemented.
- Common algorithms and their time and space complexity.
- What a CPU does, which opcodes exist for a CPU of your choice.
- Compilers and compilation.
- What a kernel does, and it’s main system calls.
- Learn at least 3 very different programming languages. I’d suggest C, Lisp and Python. The chances are that you will not find a Lisp job but it surely will make you a better programmer.
- How the Internet works: IP, UDP, TCP, Routing, BGP, NAT, DNS, HTTP, HTTPS, SMTP, load balancing, browser. Pick one of the above and read an RFC that describes it.
- Cloud concepts
Nice to have:
Become proficient with your tools if you want to be professional (read: work smarter and faster and be paid more). Imagine that you edit a text for just a few hours a day as part of your job. Invest a few days to learn more editor commands in order to become 10 or 20 percent more productive. This pays off quickly. Continue smart investment of your time by learning bits that will help you the most.
Programming languages are among the tools you will be using. One of the best investments of your time would be a deeper understanding of the language, and it’s tools.
Never stop learning! Among other benefits, this should improve your learning skills. This is one of the important skills you need to do your job.
See also: discussion about this post on Hacker News.
That was my opinion. Would you add any other points?