Many people talk about the things a software engineer needs to know in order to be successful in their job. Other people talk about the traits needed to be successful. Typically, these posts may read differently but there are many similarities between the two posts. In reality, a software can never really be successful without looking at both types of posts. The list of 15 tenets below is my hope to consolidate the ideas into one handy list for your review.
- Remember the basics. If you forget the basics of a programming language, you lose your foundational knowledge. That is never a good thing.
- Always assume the worst case. If you had formal computer science education, you learned about big-O notation. Knowing why an algorithm has no chance of performing well is a good thing. Figuring out why a particular use case seems much slower than others is how you stay successful.
- Test your code. Ensure you have tests for your code, whether you follow TDD or any other method. Depending on the type of test, you may want to target a different level of coverage, but you should still write as many tests as you can.
- Do not employ new technologies because they are new, use them because they solve a problem. As technologists, we tend to follow the hot new tools in the hope of finding a silver bullet. Utility is the key, not coolness.
- Read, a lot. If you are not reading about our industry, you will fall behind and that could have career threatening complications.
- Try new techniques and technologies, a lot. Yes, I said not to use new technologies just because they are new, but you do need to try new things in order to determine if something new is useful. Also, trying new things helps you learn and keep current in your industry.
- Fail, you will learn something. At the minimum, you will learn what does not work and you can refine your solutions. In some case, you can even consider the failure a small success.
- Ship the damn software. Sometimes you just need to get the job done, but you must be aware of technical debt. If you continuously just ship software without removing technical debt, you are well on your way to creating a nightmare when a major production issue arises.
- Do it the “right way”. Most developers have an idea of the “right way” to implement a design, but that may not always be what project management wants. This is almost a contradiction to the previous “ship the damn software” rule, but there is a balance that needs to be met.
- Leave the code better than how you found it. Instead of preaching the benefits of refactoring, think of whether you want to maintain the pile of code that keeps getting worse. If you clean it up a little each time you modify it, then it will not be a terrible mess.
- Think about concurrent access. If you are building a web application, and I don’t mean the scale of Facebook, weird issues may arise under load. Even an application with 100 concurrent users can start to see weird issues when there is concurrent reads and writes on things like HashMaps. This is just the start of the problems as well.
- Storage may be free, but I/O sucks. You may think that writing everything to disk is a great way to persist data. Generally it is, but if you use disk storage as a temporary storage area, your application could quickly grind to a slow crawl. Physical storage should be limited to that data that needs to persist for long periods of time, or when the data cannot reside in memory.
- Memory does not go as far as you may think. To start, many people will have their application and database residing on the same server. This is perfectly acceptable until both require a lot of RAM. As an example, you can easily run a Java application in Tomcat in 528MB. However, once you have to deal with scale of any sort and you add in the RAM required by the persistent storage (RDBMS, NoSQL, etc), you can quickly jump to 8GB. Obviously, this is highly dependent upon the number of users hitting the system and how much data you store in memory.
- Caching fixes everything until it crashes the server. If you are looking for ways to avoid a lot of database queries, you end up using some form of caching. The problem is that caching requires much more memory than your typical application usage, especially when dealing with data that scales with the number of users (see the previous point on memory). The worst problem with caching is that it can chew up so much memory that you run into an OutOfMemory error in java or similar errors in other languages. At that point, your server will either crash or become unresponsive and caching no longer helps because it has become part of the problem.
- Think like a consultant. As an employee, there tends to be an unwritten rule that the company can do things they would not do with consultants. Deadlines may be moved, scope may be increased, and the developer needs to find a way to meet these new constraints. As an employee, you need to use your power to state that the deadline can not move due to the amount of work required, or that scope cannot be increased without increasing the number of resources. Consultants tend to be allowed to manage a project differently than employees, and it is our job to change that.
I know there are a bunch of other ideas that keep running through my head, but this is the best list I can create for now. What other rules would you include for software engineers?
11 thoughts on “15 Tenets For The Software Engineer”
1) Think through a problem or task before you start it. Try and find corner cases where errors might occur or the software will not function as the user would wish. Requirements are almost always lacking, sometimes you can be the reviewer and second pair of eyes that the author really needed.
2) Be “situationally aware”, this is, aware of what your tem mates are doing and how the software design is shaping up. This can save you a lot of time, over the duration of a project. Skimming commit logs and code changes for important or relevant commits is usually enough.
I definitely like #1, think first should be something everyone follow. #2 is interesting and makes sense within a team. Part of that is communication within the team, and I wonder where the line between common sense and things to remember should be drawn.
#1 Details matter, nothing is arbitrary. Randomly guessing at stuff leads to technical debt, even if you don’t know it at the time.
#2 All levels must be organized. Anywhere in the system/project, if there is more than one of something, then it needs some organization. Currently there many only be three things, but that always changes …
#3 Understand the larger context. All programming happens for users, stackholders, managers, etc. in projects that are frequently done in an organization with its own unique problems. All these factors affect the underlying design/development and they are always in flux. This controls whether or not you are writing the right thing, at the right time, for the right people.
#1 is something I always assume, so I did not think about including it. Maybe I shouldn’t be assuming that. #2 is another core assumption and it feels like micromanaging a bit. This is also something that comes with experience or mentoring as well. Mentoring is something that I forgot about in my list and it really should be mentioned. #3 is highly dependent on context. In some cases, it may be simpler to write something without knowing the big picture. Sometimes it can be due to the fact that this module is fairly self-contained, and other times you actually do not want the big picture to clutter your thinking. I understand what you are talking about though.
What I seem to be finding lately is that #1 and #2 don’t come naturally to people entering into the profession. Thus I’ll meet a reasonably experienced programmer who’s work is very disorganized at the higher levels and a lot of the details are just chucked into the code (without thinking). If it were just people in their first few years, until they’ve learned from a mentor, that would be good, but lately I’ve come across veterans who are still flailing at it. I’m guessing they’ve never worked with someone way more experienced, and so their bad habits have become reinforced.
I’m also thinking that we need to do a much better job of listing out software development 101. There doesn’t appear to be one consistent place where we can point, that says “These are the absolute minimal rules that have to always be followed, or bad things will happen”.
For #3 I think you’re right, but somebody who is technical, somewhere up the latter should get it or the work may be (probably will be) seriously misdirected.
It is very disappointing to hear your recent experience for #1 and #2. However, I think this is line with your point about “software development 101”. I am not pushing for formal CS education, but due to the simplicity of fairly simple code, there is very little barrier to entering the programming industry. The problem becomes these ingrained habits when you don’t work in teams or with more experienced coworkers. I wish I had a good idea for a solution besides writing blog posts 🙂
A long time ago, I tried to write a software development 101 book, but not being a particularly good writer, and not being even mildly famous, the publishers were reluctant to touch it. That’s actually my reason for blogging. At my current rate, I’ll get both those issues sorted out in a few hundred years 🙂
Good post Rob. The rules I would follow are:
1) If you are working in a team, and are going to work on something which will take over half a day, then discuss your plan of attack for that piece of work before you start it with the reviewer. In addition to this, you need to enter this discussion willing to take on the reviewers thoughts and ideas as usually this leads to a better design. I have found in my teams that this leads to a far better first attempt at work and lessons the amount of rework required.
2) Don’t over-design. Techniques such as using design patters does lead to good code, but only if they fit and are actually required. The amount of times I’ve seen people go off on tangents trying to accommodate a design pattern into something which doesn’t require it is mind-boggling.
I think I understand what you mean by #1, but it feels like a combination of other things. #2 is an assumption I always make. Using a design pattern by default only makes sense when the pattern is obvious. I can see people eventually refactoring to design patterns, but starting with them can make things overly complicated.
[…] 15 Tenets For The Software Engineer […]
[…] 15 Tenets For The Software Engineer […]
Comments are closed.