Top 12 Things Every Software Engineer Should Know
BY MARKUS SPRUNCK
The first version of this article had the title Top 10 Things Every Software Engineer Should Know. Since then, the page has been visited by tens of thousands readers. Some gave me feedback and I learned a lot from these comments.
The list is still a personal collection of important things I could learn in the last twenty years as developer, project manager, line manager and IT architect in various industries. As an individual selection of what is important, it doesn't necessarily reflect the opinion of software engineering organizations and/or some experts.
There is no strict ranking in the list - though I tried to put the more important things on the top. The technical and business know-how is more important for younger software engineers and the soft skills getting increasingly relevant for senior software engineers.
Figure 1: Yet another monkey brain
Fundamentals of Emotional Intelligence
Almost all of us work in teams. In my first year after university, I had the opportunity to work on a clear big task without any customer and the need to talk a lot with peers. It was pure heaven. Just do a complex task and have fun with the compiler. Later the trouble started with more complex tasks, increasing responsibilities and the need to work with people I didn't liked at all. During my professional life, I attended some so called soft skill courses. In these lessons I learned a lot about communication techniques, negotiation strategies and team dynamics. All this have been mechanical tools or psychological theories. Good to know, but the concept of Emotional Intelligence is something different.
The Wikipedia definition of Emotional intelligence starts with the sentence "Emotional Intelligence (EI) is the ability to identify, assess, and control the emotions of oneself, of others, and of groups."  The important key word in this sentence is emotions. Emotional intelligence describes the role of emotions in our lives.
Some years ago, I attended a project meeting with some senior management and the boss of my boss said something to me which sounded like "Markus, you forgot to give me the information XYZ in time!" I felt embarrassed, like a culprit and explained him that he was not right. The result was that I won the discussion with him and from that day I lost an important supporter in the company. My reaction was stupid and worthless. Yes, I won one battle, but lost the war.
The root cause of this disaster was an automatic reaction on my site and a reciprocal effect between this senior management guy and me. With a better sense of self and self-regulation, I would have been able to manage the situation in a better way.
If you leave sometimes a meeting and say to yourself "Oh shit! Why did I say this?", maybe it would be a good idea to learn something about Emotional Intelligence and yourself.
Algorithms & Big-O-Notation
When I started to develop software, it was absolutely necessary to know a lot about data structures and algorithms. The reason for that was the missing availability of standard implementations. Today most languages have comprehensive libraries for container, sorting and other operations.
Still, it makes sense to know more. There are two main reasons:
Correct use of the standard libraries and
Sometimes you need individual solutions.
You should be able to analyze your own or others code. The Big-O-Notation is the standard method to describe the expected consumption of time or memory depending from the number of data. 
If a manual analysis is too difficult, just make a micro benchmark and measure with test data of different size. Draw it in a plot and find a good fit of a possible model function. This is always better than nothing.
Basics of Project Management
Even you don't like to work as a project manager; your work most of the time in teams and at least have to organize your own tasks. To get along with your technical leads you should understand their wording and way of thinking. Spend time to learn about management, because sometimes you should manage these guys.
A good example is effort estimation. My personal experience says, that if you ask a software engineer about the effort of a task you get in 80% of the cases a dramatic underestimation of the effort. A software engineer tends to estimate just the good case without unexpected problems.
This causes delays and/or poor quality because quite often the unexpected problems just happen. Another problem is the Definition of Done. The project manger means everything is done and often the developer estimates just the technical stuff.
Last week I had such a case. The developer estimated just one week of work. And after a complete planning, we saw several months' effort. The developer estimated the time for implementation and forgot to estimate documentation, security concept, data protection issues, alignment with workers' councils, reviews, project management efforts, deployment, etc.
Mainstream Development Paradigms
The discussion what is the best programming language has a religious character, it's more a question of belief. I don't like to preach my personal belief about the best languages here, but one thing is important: "Learn more programming languages, at least one for each mainstream development paradigm."
Procedural programming languages (C, COBOL, PL/I, FORTAN, etc.)
Object-oriented programming languages (Smalltalk, Java, Kotlin, Swift, C++, etc.)
Functional programming languages (Erlang, Clojure, F#, etc.)
Declarative programming languages (SQL, XSLT, Regular Expressions, etc.)
It's a good idea to know at least one multi-paradigm programming languages like Python, Java, C++ or C#. You find many lists of programming languages by type or other categories in the web .
Depending on your industry, personal preferences and daily tasks you should select your individual top 1o list of programming languages. Learn them and try to use at least 3 of them on a regular base. The old saying "If your only tool is a hammer, all your problems will look like nails" is particularly true for development paradigms.
Basics about Software Security
Even if you are able to develop software with the right functionality and performance, it is not guaranteed that your software is also secure. In the last years security got more and more important and in future this topic will be extremely important.
A good entry on this topic may be the OWASP - The Open Web Application Security Project. 'The Open Web Application Security Project (OWASP) is a worldwide not-for-profit charitable organization focused on improving the security of software. Our mission is to make software security visible, so that individuals and organizations worldwide can make informed decisions about true software security risks.' 
It includes a ranked list of the most common and dangerous Application Security Risks.
Know your Development Tools
There are a large number of tools specializing in different disciplines like: requirements management, software & database design, software configuration management, build & deploy, continuous integration, development, debugging, profiling, code analysis or testing.
It should be mentioned that a specialist from infrastructure/operations have also toolboxes with interesting capabilities, e.g. network monitoring, network analysis, operation system analytic, penetration testing, log file analysis, database performance tuning.
A software engineer can't know all tools in detail, but he/she should know the key concepts and underlying technologies. Knowing the right tool and how to use can increase the productivity and quality. Spend some time to learn about tools.
Don't Trust Code without Adequate Test
Ten years ago, I trusted my code. Why not? After 8 years C++ with excellent skills and a lot of experiences, I just coded, tested and everything was working well. But over the years I made and saw a lot of errors. Because of these errors, I lost the trust in my own and others code.
Today, I don't trust code until it passed:
Integration & system test,
Checks of performance and memory with real world data (see Big-O),
Static code analysis,
Measure code coverage of test,
Load & stress tests and
This sounds over engineered, but you have to spend the time either during development or during maintenance. I favor to do the work once with good quality and not to spend my time with troubleshooting.
Key Metrics of Software Development
Know what happens in your software, process, team and your own work. It is very difficult to control something what you can't count. I encourage you to have questions and try to find a real world measure as an answer. Then you can have target values, do your work and find out if it worked out. Important is the word "real world measure".
In software engineering we find a lot of obscure measures and/or derived metrics. E.g. The so called maintainability index (MI) :
MI = 171 - 5.2 x ln(avgHV) - 0.23 x avgCC(g‘) – 16.2 x ln (avgLOC) + 50 x sin (sqrt(2.4 x perCM))
where HV is the Halstead Volume, CC is the Cyclomatic Complexity, LOC is the lines of code and perCM is the percentage of comment lines. This is not what I call a real world measure and I don't understand this.
My advice is easy: "Never use a measure and/or metric you don't understand 100%. Sometimes it is enough to take some glass nuggets and count them."
The Root Cause of the Last Defect
Maybe your last error was not as severe, but to learn more about the root cause and negative effects you should analyze it.
What was the root cause?
In what development phase came the error in the software?
How could it be detected earlier?
Would a tool help to avoid it?
Would a rule help to avoid it?
Was it a qualification problem?
Is the working environment (lot of interruptions, etc.) the root cause?
Is it a documentation problem? Or maybe a communication problem?
What are the costs to fix it?
Are in the affected component more errors?
Are the test cases good/complete enough?
You see a lot of questions and the list is still not complete. The most important point is, to find the root cause to get better over the time. This works for your own qualification and way of working. And it works for your team. You just have to ask some question.
Understand the Business of your Customer
How can you design and implement good software without deep understanding of the purpose or use? The answer is easy: "If you don't know the WHAT, you can't decide about the HOW." A deep understanding of your customer's and/or user's business will lead to better requirements, designs, implementations and tests.
Most of the software's functionality creates no business value. The challenge is to select the functionality which creates business value. The better you know the business the higher is the probability to implement the best system.
Understand the Infrastructure
I spend my first 10 years in IT without thinking more than a minute about infrastructure. It was not necessary, because I didn't work in an enterprise environment. At the moment I am working for a bank (sorry for these Lehman Brothers stocks, nobody asked me). In a bank, you have a lot of these infrastructure people. They are really different from software engineers. But, I don't like to discuss here the differences and possibilities to get along with them.
Important is their language. Infrastructure peoples talk in "Information Technology Infrastructure Library (ITIL)". Spend at least some days to learn this ITIL terminology.  Some terms are completely different uses as developers do.
The second important thing is, that in infrastructure the people are much more specialized than developers. Sometimes a developer has just one question and needs five infrastructure guys for the answer. The ITIL stuff is maybe the glue between the people in the infrastructure.
Know What You Don't Know
This is the maybe the most difficult point of the list. To get a better software engineer lifelong leaning will be necessary and this should be planned in some way. There are two important aspects.
Firstly, you should be able to assess your own skill level. You should know The Dunning-Kruger-Effect in Software Engineering. The key message is that low-skilled developers tend to mistakenly overrate their own and others abilities. They even are not able to recognize what they do something wrong.
Secondly, you need an overview over a complete skill area. Read, for instance Periodic Table of Software Engineering - Top 118 Fundamental Elements of Software Engineering. A collection of most important and fundamental elements of software engineering. It may serve as a guideline what a software engineer or programmer should learn, know and most of them practice.