Time to move on

After 5 years working as a software engineer (and then as a principal engineer), it is time for me to leave Tripadvisor.

This has been a complex decision for me, although I am quite sure is the correct one. It got me thinking, how do you know it is time to move on? for me it meant simply to wait until I was burnt out but in the case of Tripadvisor it has not been the case.

There are are essentially three important elements that I value when I work for a company.

  • Salary: This is the obvious one, without a salary 99% of the people will simply not go to work. It is also the easier to quantify as the salary + benefits are clearly defined by a number, and humans are good with numbers.
  • Work environment: In a nutshell this is how good is your relation with the rest of the coworkers, lets face it, you spend 8 hours + lunch (so, 9 hours) EVERY week day with those people, so it is fairly important that there is harmony at the work place, it does not need to be all unicorns and rainbows, normally it is just enough to simply not have too many jerks around.
  • Career development: This is a fundamental pillar yet it is impossible to quantify. A good friend of mine says that some developers have 10 years of experience while others have a single year of experience repeated 10 times.

However in my case none of those 3 pillars were particularly bad, although they were not perfect either.

So what was it?

Ironically I started thinking about change when I was at the best moment in the company and the reason I did so was because I knew that at such time I could make a reasonable decision in order to answer a simple question:

what could possibly happen here so that I would like to leave the company?

And the important part here is that I did NOT want to leave the company at that time (neither I had the intention!) and that is exactly why I was ready to answer that question to myself in a perfectly reasonable manner.

The important thing about it is that I had a benchmark, a signal, something that will tell me: ok buddy, that’s it, remember 2 years ago when you thought about this? well, it is time to update your resume.

And that’s exactly what happened.

Now that signal/benchmark that I had is personal and private, but it is really inconsequential, the important part was to have a benchmark, a clearly defined situation in which it would clear to me that I had to move on. Such behavior is exactly what allowed me to leave the company while I was still relatively happy with it.

Such behavior is what allowed me to leave in good terms with everybody, with a bittersweet feeling yet with the absolute confidence of knowing it was the right move.

Now looking back I wish I had applied this technique in the past, however it is quite tricky, because it involves asking yourself and uncomfortable question while you are in a comfortable position. It means facing your future self and letting him know: “this is it my friend, start packing”. And to do that in reasonable terms you have to do it while you are still happy so you will not let anger or frustration overrule reason.

All in all it has been 5 great years for me, and I truly wish Tripadvisor the very best.

Happy coding.

 

 

You need to learn another programming language NOW

It does not cease to amaze me how many developers only master a SINGLE programming language. I have seen it with Java and PHP Mainly, but not only.

Declaring yourself a “Java developer” is patently absurd, it is as strange as someone declaring he is a “Toyota taxi driver”: makes no sense.

And the shocking part is that pretty much every developer I have ever met is always happy to learn a new framework of his/her preferred programming language. How can it be that developers are so eager to use the new version of Spring but are scared of diving into python?

From a professional perspective, the advantages of mastering several programming languages are multiple: to begin with it makes you more productive, also you became way more versatile, but more importantly, you start thinking different, there is a VAST difference between a developer used to the idioms and solutions of a single programming language vs a developer who has mastered several programming languages. Let me illustrate this with a simple example.

Say you are given a large json document that is unformatted and you need to format it, we are taking about a document of around 100MB, how would you do it? Sure, you can use java and the excellent jackson library, modify the default behaviour of the ObjectMapper class to pretty print and then write it into a file… However that is going to take quite a while, you need to start a project, add the jackson dependencies and so on… What happens when you are comfortable with python and bash?

Now, do not take me wrong, I LOVE java, it is possibly one of the best languages in history, and I think it is not going anywhere, my whole point here is that it might not be the best language for every situation, that’s all.

The same can be said of people using PHP for pretty much for everything, including command line executions… while you can do that with PHP chances are you are much better off with python (which has a much better multithreading support, for example).

And again, the same goes when you have a COMPLEX project, in that case Java is possibly the best choice as it has great support out there and a solid set of libraries, not to mention the foundation classes which are simply great.

So why is it that there are still so many developers out there who only code in a single language? I found that incredibly limiting, furthermore it kind of tells me that those devs are either fanboys of a language/platform or simply not passionate enough to learn a different technology.

I can code correctly in Java, Python, bash (as long as you are willing to hear some swearing every time I fight the syntax) and PHP (yes, I know, not the best one there). Additionally I can read and make changes to Javascript.

A final note: The hardest language to learn is the first one, once you have got the grasp of a general programming language, learning another one is normally much easier.

In short: push yourself to learn new things, if possible try to learn something radically different, try to get out of the JVM (which we all love, but there is life outside of it) and discover some new worlds.

Happy coding.

 

The bare minimum you should be able to cover in an technical interview (II)

This constitutes the second part of a post. Find the first part here.

5-Solid understanding of databases.

It might seem that the “old” database systems (MySQL, postgres, Oracle…) are not as cool as the new noSQL systems or other big-data solutions, however the truth is that they are the core of the vast majority of systems.

Understanding the benefits, limitations and trade offs of database systems is key, in an interview you should be able to clearly and confidently talk about:

  1. The SQL query language, specifically you should be able to to write queries with a number of joins and filters.
  2. The indexes of tables and their limitations: Why adding an index is (normally) the way to solve a slow query? what happens when that is not the case? what is the penalty for having an index? which kind of data structure does a database use internally to represent an index? All of those should be questions that a strong candidate must be able to answer with confidence.
  3. Query improvement: Are you able to analyze a query? you should be familiar with different techniques and tools to figure out where the bottleneck of a given query is.
  4. Connection leaks and connection pools: What does each of those terms mean? why use a connection pool, what is the effect of connection leaks? It is the job of any decent developer to be aware of those elements.
  5. Security: Databases end up storing very sensitive information, there are different techniques to protect such information and there are, likewise, a bunch of bugs/malpractices that can expose such information to the wrong people. Yes, I am talking about SQL injection (among other problems), one would think that by this time developers would have learn their lesson, right?

6-Talk about your own history and your mistakes.

No spoiler alert here: we have all made mistakes, I have quite a bunch in my own history… fortunately I have learn from all of them, and I have really not repeated them.

If you think that is not your case, think again. Unless you have been in the industry for too little, chances are you have been involved in some sort of mess up: maybe it was not your code, maybe you just approved the pull request, or maybe you just designed the software in a way that it became a total mess: it is all ok, really it is.

Even the NASA engineers have made memorable mistakes, why would you be free of such mistakes? The only good thing of mistakes is what you learn from them, try to visit your own failures: what happened? why? did you take responsibility? It is true that some times software developers are put in a position where it is very likely they will make a mistake: projects with terrible architecture, managers that are just pushing for dead lines… the list goes on. But it is still YOUR responsibility to make things work or raise your voice to warn about the consequences.

Whenever I interview an engineer who claims he/she makes no mistakes I always think that the person is either a genius or an arrogant candidate. It takes quite a level of maturity to recognize your mistakes, I certainly respect that.

7-Talk about your own history and your … successes.

Finally: be ready to talk about that project where you nailed it, or that bug that was so hard to fix but ended up fixing that problem that everybody had already given up on.

One of the most satisfactory parts of being a software engineer is the professional reward that we can experiment almost every week by either delivering a new feature or improving an existing one.

You should have 2-3 cases where you where particularly brilliant. Even if you are just a junior developer with 1-2 years experience there must be something that you are proud of, or something that went better than expected, hell you might have even deliver a project ahead of schedule (a rare circumstance… but absolutely epic whenever it happens).

8-You should be able to convince your interviewer that you are a nice person.

This might sound too obvious or maybe out or place, but it is fundamental.

A technical interview is a process that tries to answer two simple questions

  1. Is the candidate technically sound?
  2. Would I have a beer/tea/coffee with the candidate?

We have well covered part (1), but you should really be ready to cover part (2), after all software building is a team effort, developer teams go through a lot: good and bad times, moments of joy and tension… You really need to be a nice person to fit in well.

If you think this is not so important, think again: A junior developer can improve over time to became a senior one, but a senior developer who is a jerk cannot be fixed. Who would you be willing to work with?

This concludes the minimum you should be able to cover… I really hope these advices will help you in your interview processes.

Happy coding.

The bare minimum you should be able to cover in an technical interview (I)

I have been doing technical interviews for around 8 years, and it is not easy to find great candidates, probably because great candidates last very little in the market, however time after time I deal with candidates that, unfortunately, are not able to cover certain basics, lets go through them.

1-Big-oh notation, time and space complexity.

Being able to determine when it is worth to optimize an algorithm is absolutely fundamental, I have seen codes where collections of 100 elements were sorted because a search will be performed once or twice… that says a lot about developers.

Also, it is important to understand how bad or how well out algorithm will do as a function of the size of the input. An image is worth more than words, so here is the fundamental picture to keep in mind.

bigh oh runnin times

Anybody doing an interview should have that picture really clear in their heads. The reason? lets go through a simple question: lets say you have 1 million numbers, unsorted, and you will need to search whether or not a given number is in your million numbers, such operation is to be repeated 100 times. Is it worth sorting your 1 million numbers or not?

It is a simple question, and it should have a simple and definite answer, however without the help of the big-oh notation and some knowledge about the running time of sorting and searching algorithms, it is impossible to answer it.

However, with the help of big-oh one can answer this question very effectively.

Doing a sequential search will take linear time, that is \(O(n)\)
Doing a binary search will take log time, that is \(O(log(n))\) but in order to perform a binary search we first need to sort. Sorting takes \(O(n*log(n))\) now, in our case we are specifically dealing with \(log_2(10^6)\) which is approximately 20 as \(2^{20} \simeq 10^6\)

This means that

  1. Using a binary search will take around 20 operations (worst case) to find a number
  2. Using a sequential search will take 1 million operations (worst case) to find a number
  3. The cost of preparing our numbers to be able to perform binary searches is 20 million operations

Now, lets ask ourselves the question again. Is it worth sorting 1 million numbers if we are going to search 100 times within them? The answer is yes, as our initial cost is 20 million operations, but after that, the cost of a binary search is almost none, while a sequential search will take 1 million operations each time.

2-Basic data structures.

The simple data structure is an array, but everyone should be familiar with stacks, queues, linked lists, hash tables, trees, graphs and possibly also sets and heaps.

Furthermore, I expect people to be able to implement any of the structures mentioned above. Sure, you will NEVER implement those in real life, but I think it is an interesting exercise to be able to implement those by yourself. I tend to ask people how to implement a simple Stack, and some people really struggle to do so, I would never ask anybody to implement a full hashtable, but I will certainly expect them to be able to do so if a hash function is provided to them.

Being familiar with data structures is key for being able to solve problems, here comes an example: Imagine you are given all the correct works of the English dictionary, how could you implement a spell checker that will not only inform the user if the work they type is correct, but also provide them suggestions in the case the wrote an incorrect work?

Most people will initially resort to a hashtable, however there is a problem with hashtables: they only help you with exact searches, if you type “helo” there is no way to let the user know that maybe he wanted to type “hello” or “hell”. How would you do that? The solution is a trie, a type of tree where each level contains each of the letter of the alphabet, if a particular node is a word, then it will contain a flag indicating so, again lets illustrate this with a picture.

This is a simple yet interesting example on how a problem that might seem very complex at first could be effectively solved using the right structure. Most people operate with linked lists, sets and hashtables pretty much every day, however trees, graphs and other structures might not be used so often but they are incredibly powerful in certain situations. As a software engineer it is your job to know your tools, and data structures are pretty much tools 101 here.

3-Basic data types.

What should you know about floating point numbers and monetary calculations? they are no-no, and for good reasons. Due to the internals of how floating point numbers are stored, they cannot represent fractions accurately, the loss of precision is not too terrible for scientific calculations, but it can be really bad for monetary calculations (or any other calculations where precision is critical). As an example a simple piece of python code (the same problem will occur in java)

Now, the expected output of that calculation should be 1, right? well, not really, the actual result is

So, if that happens after only 1000 operations, imagine what floating point numbers could do to multiplications and divisions. And then imagine what would happen if those multiplications and division involve money (currency conversion, tax calculations, margins…) Again, it is your job as a IT professional to know this and use the proper tools. Most languages provide mechanisms to deal with this problem, do you know them?

4-Basic object orientation understanding.

Becoming an expert on object oriented programming takes years, even I struggle sometime to find the right abstractions, it is a never ending process but, when done correctly, object oriented programming can solve many problems, as it allows us to work with abstractions rather than low level details.

Can you clearly explain what is polymorphism? without resorting to an example? could you explain it to your mum? that is the level you should be able to provide in an interview.

Do you fully understand inheritance and composition? Have you realize that inheritance can actually break encapsulation (if done wrong)?

I am surprised, quite often I ask candidates about information hiding and most of them are able to explain the mechanisms that languages like java provide for such technique (private, protected, public…) however when asked “why would you ever want to make something private? can you give me an example?” many people actually struggle, furthermore, many people will simply answer that you make attributes private and then provide getters and setters.

You need to understand how information hiding allows you to keep the internal state of the object separated from the outside world, you should be aware of the consequences of not doing so, and you should be able to clearly and confidently explain that.

This concludes the first part of this story.

Happy coding.

What I have learned after 12 years as a software developer (III).

This is the final post about my experience as a developer, you might want to check part 1 and part 2.

15-Fear-based management is the lowest level of management.

Nothing surprising here, if a company is managed based on fear, then people will essentially tend to try to hide errors. Sure, development errors can be easily traced back, but do you really want to generate an atmosphere where people will be making it hard?

The reality is that errors will happen, is not a matter of if, it is a matter of when, more important than the errors is the reaction to it.

Once I worked for a company and a bug was discovered, it was not too bad, but I felt that I must inform the owner, an incredible amount of people almost begged me not to do so, just to avoid the rage… It certainly got me thinking? what kind of place was that? Ultimately I communicated the problem anyway and actually the reaction to it was not as bad as people told me.

In short: do not use fear, people will not respect you, they will only avoid you, a leader will be followed to the battle field if required, a tyrant will not.

16-A single branching strategy is fundamental.

It does not matter what control version system you use, git, mercurial, svn… but whatever you do, you must have a clear and standard branching strategy, I have personally found that gitflow works very well, but I recognize that it might be too complex for simple organizations.

That said, the days of committing directly to the master branch (or trunk in svn) should be in the past, with continuous delivery one cannot afford the main branch to get polluted with bugs, the extra time required to merge two branches is minimal nowadays.

I have personally experienced the situation of a company not having a single branch strategy, the pain of getting everyone in the same standard and the benefits of it, the larger the company, the harder it gets… but the reward will also be bigger.

A branching strategy should allow you to easily.

  • Deploy your code easily and safely at any time.
  • Allow you to rollback to a previous version easily and quickly.
  • Make hotfixes easy (although hopefully this is something you will rarely do).
  • Permit flexibility in development.

My advice is to use a strategy already tested such as gitflow, if you think you do not need a branching strategy, think again, it can prevent a lot of headaches.

17-Compiler warnings must be address immediately.

Not all languages benefit from this, but many do (Java, C, C++, .NET). The compiler is, with the debugger, the best friend of any developer, it saves us from ourselves constantly.

So, if the compiler is giving you a warning, trust me, you need to address it, sure the code most likely will work, but it is a ticking bomb. Also, the fact that you did not write the code generating the warning is no excuse not to fix it.

Conclusion.

Most likely, these 17 points will need revision with time, but they truly represent the most relevant lessons I have learned in 12 years.

Happy coding.

What I have learned after 12 years as a software developer (II).

12 Years as a coder (let it be junior developer, senior, team lead or principal) have taught me a lot, these are the rest of the points that I consider the most important ones, this is the second part of the article, find the first part here.

7-Having a proper build pipeline is fundamental.

There are different ways to do this, and it will certainly depend on the circumstances of each company, but as a bare minimum you should have an integration server where you can have repeatable builds.

Of course this also means that your build process should be as simple as possible, I found it acceptable to have to execute a couple of commands to get a full build (in order to get test coverage and so on), but that should all be clearly encapsulated in your build server.

Goes without saying that if your builds fail with certain frequency then you need to stop whatever you are doing and make them stable, after all, what’s the point of deploying stuff that does not always build correctly.

It is also very advisable to control the build times, I have seen projects that take 45 minutes to compile, no matter what you do, if your build process takes 45 minutes you are not agile (and I do not mind if you do standups or not).

8-Deadlines are just wrong.

To a certain extent I understand that the business wants to get an idea of when something is going to be done (even when that “something” is not clearly defined) and I think that having a certain horizon can help to keep a bit of tension and motivation, but having deadlines is, in the vast majority of cases, simply wrong.

Lets face it, we have been doing software engineering for less than 40-50 years, we are still learning, and believe it or not, the vast majority of software projects are delayed, getting obsessed with deadlines will only lead to poor quality code that will then lead to bugs and that will cost the company.

Do not get me wrong, I am not saying that timing is not important, of course it is, what I am saying is that it should not drive the company behavior. There are interesting alternatives to plain time estimation, such as story points, t-shirt sizes, poker planning… They do work incredibly well, but It will take time until your team gets good at it.

9-Big bang deployments do not work, stop doing them.

It is 2018 and I still have conversations with developers telling me that in their own companies there is a deployment to production every month (or even every 3 months), that is simply a recipe for chaos.

It is much simpler, to deploy small and deploy often than making big deployments, and for good reasons: first, any process that is done often will get automated quickly, second if you make mistakes you will have a much quicker feedback cycle to improve it and third the business will be actually happier as the mean time to deploy a feature will be greatly reduced.

Saying that you do not have the capacity to automate deployments so they are more often is like saying you cannot go and grab a fire extinguisher to put off a fire because you are too busy using little glasses of water instead.

In short: automate deployments, make them common, small and non-scary, everyone will be happier.

10-Developers need to understand the business.

This seems obvious but unfortunately it is quite common to work in many places and when a dev is asked “why are you doing this?” it might take a few questions until you actually get a satisfactory answer, example:

-Why are you adding a table?
-So we can store product types?
-And why do we need to store product types?
-Because we want to display them in a dashboard?
-And why do we want to display products in a dashboard by type?
-So the business can decide which type needs more marketing

There we go!! this is surprisingly common, it is not due to lack of interest or lack of communication, it is just that we developers sometimes get too focus on the technical part, but I have found it incredibly beneficial for me to understand WHY things were being done and what was the ultimate goal of the feature I was building.

This is specially important in startups where things are a bit crazy (or fast-paced, whatever term you prefer), in those environments there is always a fight between developers wanting to rewrite part of the systems and the business desperately trying to close the next financing round.

11-Everything else being equal, consistency wins.

We all have, as developers, our own preferences, some of them can quickly turn into religious wars (for example, where should we place curly braces? in the same line or in the next line?).

I am a strong advocate of consistency, more often than not I have actually agreed to follow certain naming conventions that I might not share, but that were well established, of course if you really see something that is wrong, by all means change it, but there are certain areas that are more preference than science, as an example, methods names:

  • User getUserById(int userId)
  • User getById(int userId)
  • User findById(int userId)
  • User loadById(int userId)

Which method is the best one? what is the best naming convention? I do have my preference, but if everyone else has already agreed to use, say “loadById”, then why should I start changing the names for other entities? what value am I adding? apart from satisfying my own preferences, am I making the code any better?

Coding software is, largely, a team activity, and there will be clashes, and there will be disagreements, be ready to bend some times and be ready to accept certain things, choose what is really worth a fight and what is not.

12-It is much easier to code things correctly from the beginning.

Ok, we have all cut corners sometimes, but honestly, looking back now, was it worth it? there are scenarios in which it is ok to do so, but to learn which scenarios are is something that takes quite a few years.

The reality is that, it will be YOU the one who will have to deal with the crappy code you are writing today to satisfy the business people, so when required, put up a fight. Know which battles to choose, as it is not always easy to win them, and sometimes put up a fight, even if you know you cannot win it, it sends a message.

But to be fair, in many cases the fault is not on the business, it is on us, after all, it is the job of the business to keep the money coming and it is YOUR job to deliver high quality code, this means writing tests constantly and as you are developing your features, not at the end “if you have time”, tests are part of the code I expect developers to deliver, plus they have saved my ass so many times that I have learn (sometimes the hard way) to write them and give them the importance they deserve.

Also, every time you write bad code, you are sending a message to the next developer that it is fine to do so, this is closely related to the theory of the broken window which essentially establishes that if your code has dirty areas, the rest of the code will not be respected and will get dirty too.

13-It is incredibly inefficient to use the same technology for everything.

So, yes, believe it or not there is no silver bullet. This is one of those recurrent mistakes I see in developers specially, I have heard so many times people saying “I am a Java developer” (or php, or ruby, or python… whatever you prefer), it is a terrible mistake, and it is as absurd as saying “I am a Toyota taxi driver”.

Why do we get obsessed with a single programming language? sure I love java, but if you want to build a single page with a form php will do better, or if you need to analyze a csv file python or R will be fantastic.

The only thing a developer should never stop doing is learning, there are an incredibly large number of technologies out there, sure you can not learn all of them, but before you start writing a complex data structure in java to handle tables, you might want to check pandas or R before.

Being a developer is not so different from being a handy man, you need to to know your tools and, from time to time, TRY other tools, as they can help you to succeed, at the end, it does not matter which technology you used, as long as the code works and can be maintained, do not be afraid of going into that other programming language that has such a bad name at your office, you would be surprised.

14-When (not if) an error occurs, do a post-mortem and learn from it.

There is only one thing worse than introducing a terrible bug into a production system, and that is not learning from it.

If you have been working in the software industry for a few years, I am fairly sure you have made mistakes, some of them might be not too bad (maybe some test emails were send to the users) some others are more serious (pretty much anything related with payments). In every single case, it is fundamental to have a post-mortem so the situation can be analyzed, determine what was done well, what was done wrong and what could have been done better.

Post-mortems are one of the most effective ways of learning from our mistakes, hopefully it is not a process we do a lot, but it will happen. This is specially important for junior developers: you WILL make mistakes, but chances are it is not as terrible as you think, but if you do not learn from those mistakes and you do not improve, then we have a problem, do not be scared of acknowledging your errors in most of companies actually it is seen as a correct aptitude (and if you are in a company where there is a witch hunt after each mistake, you might want to look for another job anyway).

 

What I have learned after 12 years as a software developer (I).

I started coding professionally at 2006, at that time I was just fresh out of uni and certainly I had a lot to learn ahead of me. Over the years I have accumulated quite a lot of knowledge, part of it by simply keep myself studying and part of it out of pure experience.

Please be aware that this reflects only my own experiences and may or may not reflect other people’s experiences, we developers tend to have quite different opinions when it comes to code, that said, here is what I have learned.

1-Most of the things will not be needed, apply the Yagni principle.

The most common, by far, mistake that I see is developers trying to account for stuff that simply is not required, it does not cease to amaze me how often this happens, time after time I see complex code and architecture in place that is there because “we might need flexibility in the future”, and what happens? that future rarely shows itself.

There are may examples of this, some of them are relatively benign like declaring an interface that has a single implementation because “we might have other implementations in the future” I see this quite often with DAO objects, the reality is that I rarely see more than one implementation of a given DAO interface, and even if that happens, modern IDEs have refactoring utilities that allow to extract an interface.

Worse than that, I have seen code became very complicated to account for stuff that was not even asked for, once I had to deal with a monstruosity in java whose only job was to read a csv file, the developer (possibly with the best faith) prepare it so it could read XML, json and a number of other formats, unfortunately in the process of doing so, he got the code quite convoluted (no, it was not a simple polymorphism), the final project ended up with many dependencies, and the worst part is that it was a memory consumption beast… of course the code has never processed anything other than csv files, so what was the value of it?

2-Complex architectures are evil, evil I say!

Of course there are exceptions, in some scenarios one might need to have a complex or non-trivial architecture to solve a complex problem, but in the vast majority of cases there is a tendency to overachitect things, specially in the java world.

Most of the software that most of the developers write and maintain is quite boring, most of the cases just webpages that read and write from a datasource (a database, a webservice …), do we really need a complex architecture for that? in most of the cases what will occur is that the junior developers not familiar with the architecture will start to cut corners in order to get stuff done, at the end of it, the code tends to evolve into a big ball of mud.

Don’t get me wrong, I like when I am faced with a problem that requires a non-trivial solution, I love to design big architectures (we all do, I think), but more often than not I have seen complex architectures which mainly just satisfy the ego of the developer(s) who came out with the idea. All being equal, the simple the better.

3-If you want to generate chaos, do not use a ticket system.

As a golden rule, nothing, absolutely nothing should EVER be done without a ticket describing what is being done and why, furthermore, in my current job that is simply not possible, you need a ticket to be able to create a branch.

This rule is specially important if the ticket is very urgent or it is a blocker, precisely because of that, one needs to follow the procedure, the reason being is that the procedure is design when people can have a cold mind, so when the shit hits the fan, you better follow what your past (and calm) you decided to do.

Also, it allows to have control over changes and bring some sort of discipline to developers and non-technical people.

4-Not retaining good developers.

This is an important one.

Finding good developers is not easy, first they are expensive, second, they last very little in the market as companies will hire them quite quickly.

It is not always possible to retain every good developer, after all we live in a free market world and people change companies for many reasons, however there is a big difference between the natural turn over and simply not managing to keep people happy.

Every single time a good developer leaves, two things happens: first the company loses a lot of knowledge that will go away with that developer, and second morale takes a hit, work mates talk mainly… well about work, when a good developer leave for non-natural causes (maybe he/she is moving to a new city, maybe they are about to start their own business), the conversations for the few weeks while such developer will remain in the company will be mainly about how happy he/she is of leaving and how everyone else should do the same.

Notice that to keep people happy there are three main pillars, and they are all equially important

  1. Salary.
  2. Work environment (relations with other devs, managers…etc)
  3. Career development (how interesting are the projects, how the future looks like…etc)

It is not always possible to keep all of those three pillars up, but at the very least two of them should ALWAYS be solid.

5-Lack of system monitoring.

Software is complex, too complex, on top of that, we have been doing software engineering for maybe about 50 years, so we are all still learning (I am sure that 100 years for now, people will consider what we do as primitive as we consider now the car production systems in 1920).

Not monitoring is simply too expensive, once things stop working in production is already too late, I have seen a bit of everything, from companies with fantastic monitoring to companies with no monitoring and everything in between.

Once I saw a company’s website go down simply because they have run out of disk space which is pretty much the equivalent of not being able to serve food at a restaurant because someone forgot to buy it.

Along with lack of monitoring comes lack of alerts, a very common mistake I have seen way too often are systems constantly triggering red alerts and people became so used to false positives that they are simply ignored… until one false positive turns out to be a true positive, having a good set of reliable alerts is key to keep a healthy system, if there are false positives then certainly more work has to be done and better alerts need to be defined, ignoring the problem is not going to help.

6-Ignoring technical debt.

Technical debt is pretty much like financial debt: It is not always bad, sometimes it is perfectly fine to ask for a credit so the company can perform other investments, but leave debt unpaid and the compound interest will kill you.

There are many tools out there to control technical debt (I have been using sonar for quite a while with good results), there is absolutely no excuse to leave technical debt unpaid, it is your responsibility as a developer to push for it, because the non-technical people will never, ever ask you to pay the technical debt, you are the expert and you are paid for it, so put up a fight, sometimes you even have to put up a fight knowing you will lose it, but still it is worth to make a point (I have found however that asking people to send me an email saying they will assume any responsibility if something goes wrong, makes miracles).

Along with ignoring technical debt, there is the bad practice of not doing code reviews, every code to be merged must go through a pull request, with the possible exception of hotfixes (which, by the way you should rarely do anyway). I personally like the code reviews and consider them a safety net, it has not been uncommon for me to find myself saved by another coworker after reviewing my code.

Conclusion.

This is just the first part of the post, but really hope someone finds this useful as it really represents years of my own experience.

Happy coding.