Tips for beginning systems and software engineers


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:

Human factor


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:

  1. 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:
    1. Slower development because one becomes hesitant to make changes and has to test manually.
    2. More bugs as manual tests are not as good.
    3. Bad code as it will less likely be refactored.
  2. Gradual deployment of new versions.
  3. Monitoring – detect errors/bugs in running software. Goes well with gradual deployment.
  4. Metrics – detect performance issues and errors  in running code.
  5. 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.

See also:


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:

  1. Your task will take more time and effort than you estimated.
  2. The resulting code will make the system much more complex and will be a nightmare to maintain.
  3. 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.


Code duplication

Don’t duplicate code (copy+paste):

  1. Duplicated code means more maintenance.
  2. Duplicated code may some day be updated in one place and not the other, causing bugs.
  3. You will be looked down upon by senior developers as this is a big no-no.
  4. This rule has rare exceptions, use your judgment. If not sure, don’t duplicate.

Code reuse

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.

Code style

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.

See also:

System complexity and code complexity

Strive for simplicity. More complex systems:

  1. Are harder to maintain
  2. Are harder to add new code to
  3. Have more bugs
  4. 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:

  1. Avoiding boring repetitive tasks
  2. Minimizing chances of mistakes (common in manual tasks)
  3. Describing the task for your future self and others
  4. Allowing others to do the task easily
  5. Increased productivity

Important defaults

Here are important defaults the can save you many tears. Deviation from these requires justification.

  1. UTF-8 for character encoding
  2. For servers: UTC time zone

Knowledge and proficiency

Theoretical knowledge

A must:

  1. Big O notation.
  2. Common data structures and how they are implemented.
  3. Common algorithms and their time and space complexity.
  4. What a CPU does, which opcodes exist for a CPU of your choice.
  5. Compilers and compilation.
  6. Interpreters.
  7. What a kernel does, and it’s main system calls.

Practical knowledge

A must:

  1. 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.
  2. 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.
  3. Cloud concepts

Nice to have:

  1. HTML / Javascript (reading the spec would be very nice)
  2. Character encodings and UTF-8 in particular


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?

18 thoughts on “Tips for beginning systems and software engineers

  1. >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.

    Ok. Which RFC describes web browser?


    • It depends on what you want to learn (disclaimer: I’m a back end developer). RFC 2616 will teach you how the browser interacts with the server. There might be some value in looking at the w3 references for things like the DOM, CSS or maybe the ECMA specs, although I’ve never been through them. Whenever I’m experimenting with new (HTML5) features I usually go through the spec first.

      There are some things about the browser that will likely never change and are important to understand. These include the way it interacts with the server (via HTTP, WebSockets), the separation of concerns (i.e. components like HTML, CSS, DOM, Javascript) and the consequences of its concurrency model (the run to completion event loop).

      At the end of the day, the browser is a run time that is under-constrained by specifications with a number of key implementations and a no-batteries-included language. You will ultimately end up building on abstractions, so understanding these abstractions is important and likely the best use of your time.


  2. Never hesitate to build your own tools, and do tune/hone/maintain what you have.
    Now, “tools” means quite a lot of things: even languages are tools, make them up when needed. Big or tiny.
    And a non-technical advice: Find friends. Doing software is social activity, Lonely heroes don’t get too far anymore.
    Ah, and have fun.

    Liked by 2 people

  3. Funny you have both: “Professionals usually avoid doing tasks which are “nice to have” ” and “Practical knowledge -> Nice to have” in your text.


  4. The Big O notation and time/space complexity items are (in my experience) only relevant during an interview. I’m a compilers/interpreters/runtime/virtual machine developer, so not sure whether Big O and time/space are relevant in other domains.


    • I suspect you use the knowledge you gained from learning Big-O notation on a daily or weekly basis, but it’s become so ingrained that you don’t think about it. The important aspect of Big-O notation is not that you’ve learned how to precisely characterize the running times of two complicated algorithms, but that you learn that there are fast and slow algorithms, roughly how to identify them.

      It’s where you probably picked up the basic skills to look at a set of nested loops and think, ‘yeah, the outer one is only ever going to have three elements, and the inner one is bounded to about five, so it doesn’t really matter if I’m counter calling this ten thousand times,’ or ‘I really need to figure out a better traversal order for these two million-item sets because it’s going to be untenable to do it the obvious way with two nested loops.’


  5. On-topic: learn to differentiate between unnecessary duplication (copy-pasting code blocks), and unavoidable duplication (design patterns). Most languages aren’t powerful enough to abstract away all duplication, which leaves you with recipes for accomplishing specific tasks.

    Off-topic: your links look like regular text to colorblind users. I highlight text when I read, and I kept clicking through to links I didn’t realize were there.


  6. Learn to navigate with the keyboard and use keyboard shortcuts. Cutting and pasting, for example, is much faster when highlighting with shift + navigation keys followed by CTRL+C and CTRL+V instead of the mouse. It holds true for all keyboard shortcuts in your favorite editor.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s