Is Working Late Good?

If you’ve been working in a team, in an office, for any length of time, you’d surely have noticed that the people can be starkly divided into two categories – the people who stay back and work till its late, the people who pack up and leave sharp at their clock out time. As far as I have seen, the people who stay back are perceived as people who work harder than others – both by themselves and others. For every manager who has insisted people go home on time, I’ve seen probably ten managers who encouraged the staying-late behavior and rewarded people for putting in more hours.

My opinion – a rather strong opinion – on this matter is that people should not stay late for work. Just think back about the basics. Are you working because you have nothing better to do? Or are you working because you need money to live your life? Most probably it’s the latter. Therein lies my opinion. I feel it’s sad if anyone sacrifices their family time, their hobby time, or even their just-me time for the sake of working a few more hours. If you are not even living a life you wish for, then what are you working hard for?

It’s Not Really Rewarding

It is seemingly rewarding – but it’s often not. You would have seen that people who stay late get praised and a lot of times they are the ones who get the hard tasks finished. But when it comes to being rewarded for it, it’s not really worth it. If you have any doubts just look around at your office. The ones that are well rewarded are usually the ones who leave office on time. There’s a reason to it. More often than not, people who leave office on time, surprisingly, are the ones who are more productive, and plan their work better. That’s another thing to debate, I know. But the more important point is, late hours does not imply faster pay raises.

It Cripples You

Here is a difficult question for you – What is more important – achieving your current week goals, or achieving your five year vision? It’s a tricky question because obviously you should not default on your current commitments in favor of your future dream. It’s also wrong to simply be drowned in day-to-day commitments without a vision for your future. If you exhaust all your energy thinking about what you can contribute for the day, how are you going to plan for your future? Not a single one of such people I’ve come across, worked towards, or even cared for their long term goals. Day after day they just slogged with whatever tasks they’ve taken up for the day.

It’s Unhealthy

Of course you already know that it damages your health and fitness to spend prolonged amounts of time at work on a regular basis. But it’s more than that. It also affects your health in indirect ways. For example you don’t have enough time to relax and recharge – this tires your mind, reduces your productivity. So you end up working even more to cope up. It becomes a cycle. Also, the more time you spend working, the less time you have to socialize with other people. It is actually very important that you have face-to-face interactions that are not just for work. It is linked to mental health, longevity and even physical health. In other words, make time for your friends and family – you will live longer.

It’s Bad Culture

If even a few people in a team become available for after-hours, a very bad thing starts to happen. All the planning and task scheduling starts to rely on the fact that people will work late. It is already human nature to over-estimate what we can do in a given amount of time. Adding more hours amplifies this error even more. Sometimes it even unfairly forces other people to put in more hours than necessary. For example, if your manager asks the team whether a task can be completed in half the time, the people who stay late will probably say yes. The others will not want to appear incompetent, so they will also say yes. I’m not saying it’s bad to be competitive, but I’m saying for most jobs, working with commitment for the agreen upon 9-to-5 is already competitive enough.

You’re Probably Slacking

Except for a very few workaholics, I have hardly noticed any correlation between higher hours and better productivity. The people who stay late spend more time doing things like chatting, taking breaks, browsing the internet. They have too much distractions to finish their job on time. It is to make up for this that they stay back late. Also, because of not managing time properly during the day, they often get stuck delayed on their tasks. So they often don’t have a choice, but to stay late and finish their task. I say this because even for the very hard working people I know of, staying focused for more than a few hours is not possible. If you are a hundred percent focused on your work, for about 6 hours a day, you are already ahead of most of the people working day jobs.

But There’s an Exception

One exception is when you consider your job as the most significant feature of your life. Then you are living the life you wish by working late. But I doubt this is the case. Most jobs today don’t really give the fulfilment of contributing meaningfully. I’m not saying it’s because they are not useful, but rather it’s because any meaningful task today has to be broken down so much that in isolation, it’s very hard to feel what you are doing is meaningful. Or in other words, your company’s product might be impactful, but your contribution is most probably a small cog in it. If you want to find out if this exception applies to you, think whether you are working late because you are motivated to solve a problem or to make a contribution? Or are you working late because you want more salary or to get ahead of competition? Simple.

Conclusion

It would be wrong to say that no one should stay late at work and it’s simply enough if every one just works the time they committed to. There are scenarios where you have to – and you must – give importance to work and sacrifice a little bit in other areas. So I will put it like this: Valid reasons to stay late at work –

  • There’s an unexpected problem at work and it needs to be resolved right away. But it’s just an isolated occurence. You need to be late just the one odd day.
  • You are driven and completely motivated by your job. You are trying to churn out an impactful product / service that would give you so much satisfaction.
  • You are the CEO of your company. If you are CEO (or another designation that’s right there on the top), it’s not really possible to expect it to be an 8-hour job. It’s unfortunate, but that’s how it is.

If those three points don’t apply to you, there’s no reason for you to stay late. You’re probably making a mistake by being occupied with work more than necessary. You need to fix this and manage your time better.

Are Unit Tests Over-Rated?

Having worked in software development for more than 12 years now, I can safely say that about 20% of the projects I worked on, had unit tests. And none, had unit tests that were actually effective. Yet, I wouldn’t call even one of those applications as poorly written or of low quality. In fact, most of them were quite good – even in terms of maintainability and code quality.

One reason why I think unit test presence was low, is that all software I worked on were customer facing web applications. The emphasis was more on integration tests. I can’t help but think – is it really bad? I think it’s not. While I do recognise a lot of situations in which unit tests might help save the day, I don’t believe in having mandatory requirements of meeting a certain percentage in code coverage. The project I’m working on currently for a multinational corporation, has a 90% code coverage requirement.

Are your unit tests actually testing your code? Or are they just helping you achieve a code coverage metric?

Reasons against Writing Unit Tests

1. Code is not Reused Anyway

In a web application, except for a very little part, methods are always single use. When the code is divided into methods, its mostly for reducing complexity, making it readable and in general having modularity. Think of your typical method – validateTableCreationPayload(), createUser(User user), deleteBook(int bookId) and so on. These methods are going to be used in only one other place in your application right?

It’s quite easy to ensure changing the method doesn’t break the one, single usage of it. And when it does break, almost always, the unit test is what gets rewritten. That’s the thing with application code – you’re not going to deny your client’s requirement just because your unit test fails right? And there is nothing dependent to be changed – remember there’s only one usage. Considering that none of the functionality is breaking – and your integration tests ensure that, unit tests lose much of their worth anyway. And it becomes a ritual to just change the unit test whenever we change code.

2. Sacrificing Development Speed

Unit tests for application code will take as much time developing the actual code. Often, the unit tests take more time to develop than the actual functionality. An architectural purist might not even consider this as an issue. But a business manager will be – Are you saying it actually only needs half the time to develop!?

And unit tests tend to become very complex very fast. In a regular web application, you end up having to mock several components in almost every unit test. As far as I’ve seen, going beyond a certain coverage percentage, makes unit tests unreadable and off-putting to modify.

3. Misleading Sense of Security

You should always do proper diligence before modifying existing functionality. Do not ever rely on unit tests to catch these. Because unit tests are almost always insufficient. Take this example –

public void createUser(User user) {
    addMetaDataToUser(user);
    // new statement inserted here
    repository.createUser(user);
}

@Test
public void createUserShouldCallRepository() {
    createUser(dummyUser);
    verify(mockRepository).createUser(any());   
}

The above test has 100% coverage for the createUser method. But what happens if we insert another statement in the createUser method? The test still would show 100% coverage. The developer who inserts that statement can get away with not even writing unit tests for their change. Such things can only be caught by careful manual review. And unit tests are often ignored when code reviews are done. Especially in teams where an automated process reports code coverage metrics, and (wrongly) says everything is fine.

Worse, the above unit test is inadequate. It only checks if the repository.createUser() method is called. Not that it’s called with the correct argument! If the new inserted statement modifies the user argument, the unit test will still pass, code coverage will still be 100%. Bad, no?

Reasons for Writing Unit Tests

1. Documents Code

If unit tests are well written, they will act as documentation for how and why code is written in a certain way. It’s not uncommon to see a comment in code that says ‘ugly hack .. do not change this’ or something similar to that. The programmer who wrote it understands that someone in future might modify it and the fallout might not be immediate. But this assumes that nobody would have ‘cleaned up’ that comment. Or a future programmer would simply miss reading it. But if there is a unit test that looks out for this situation, that’s a way better safeguard.

Also, well written unit tests have great names that set expectations about the method being tested – shouldThrowExceptionForBadInput(), shouldReturnAValidUuid() etc. Also, these are arranged in neat groups in your test classes. So if your developers follow discipline you can take a look at the unit tests and learn a lot about the code.

2. Protects Sensitive Methods

General purpose methods, which are used all over the application need to be protected from change. For example, if you have a validation method that checks if a string has a particular pattern (maybe your company has a certain pattern for unique IDs), it is very risky if someone modifies this method. Every method you have used twice or more in your application, must have a unit test. The method serves for two tasks. What if you change it for one task and the method no longer works correctly for the second task? Preventing this, is the core purpose of unit tests. Unit tests serve as a guarantee to what the method will do and will not do.

3. Improves Code Quality

In my opinion, this is the number one reason to enforce unit tests. Especially if there are inexperienced developers in your team. If you write bad code, it becomes more difficult to write unit tests. In my initial days as a developer every time I struggled to write a unit tests, it showed me how I could have written my code to be more loosely-coupled, modular and simple.

Your function might have to be broken into pieces, if you are writing too many unit tests for it. Your function is too tightly coupled, if you are writing too many mocks. Are you finding you need to inject ‘private’ dependencies using Reflection? Are you unable to write a unit test because one of your private fields is initialised indirectly (like Spring’s @Value annotation)? Just about every time you find yourself writing unit tests that are too complicated, you can see opportunities to simplify your original code.

Conclusion

Now, if I propose we write only minimum required unit tests, I would be no different from the people who tell me to write the maximum possible unit tests. But one thing is obvious to me, having a code coverage target is pointless. Only the developer who is writing code can decide which part of it has to be registered in unit tests and which parts don’t quite benefit from unit testing. If you don’t give importance to unit tests in code reviews, don’t even bother requiring them – at least your development will be faster and your code base will be cleaner.

What Slows Down Software Development

Delays in delivery is so common in the software development world, that it has become a common practice to include a ‘buffer’ time when giving commitments. And the sad thing is, we face delays even after including such a buffer. There are two sides to this problem – either the task has not been sized correctly, or the developers were slow in delivering. I thought of things that causes slow development and could find these major factors slowing down development for me –

  1. Starting Without Clarity
  2. Not Asking Questions
  3. Lack of Knowledge and Skills
  4. Not Getting it Right the First Time
  5. Not Considering All Activities
Photo by Braden Collum on Unsplash

Starting Without Clarity

Developers just break out their editors and start coding right away when they get a task. Almost always the task definitions will have gaps in them. It was probably written by a product manager or a technical architect. Only the developer will be aware of all the little questions that will arise while carrying out the task. So after taking a look at this task, ask questions that help you clear out any vagueness about the task.

Questions like ‘What errors must be returned?’, ‘Are there specific expectations on code quality?’, ‘Does the architect prefer using a certain design pattern?’, ‘Has the task considered its side effects?’ and so on, must be thought of by the developer when they start. Simply put, start with a clear end in sight.

Another thing that helps to achieve this, is to do test-driven development (TDD), where your tester first writes tests that are supposed to pass after the task is done. When you have actual tests, you have so much clarity on what needs to be done and can minimise the number of doubts that will rise later.

Not Asking Questions

There seems to be a lot of hesitation in today’s developers to ask questions. It mainly comes from either being an introvert, or by the doubt that your question might be stupid. Remember – Asking questions doesn’t make us stupid – making assumptions does.

And it also has a spiralling effect. The first time you might feel a little stupid to ask a question and carry on with your own assumptions, ignoring the fact that you are creating a gap in your own understanding. As time goes on and you avoid asking for clarity more and more, the gap keeps widening. At one point, you just can’t bring yourself to take a step back and ask your question for the fear of coming across as ignorant.

Stop worrying that your question might make you look less intelligent, or that you might be disturbing people if you raise questions. Software development is a lot about collaboration. People who don’t collaborate inevitably end up failing in their job.

Lack of Knowledge and Skills

As bitter as this factor may be, it is definitely a fact that lack of knowledge and skills in the developer is one of the top causes of slow delivery. There doesn’t even seem to be a motivation to learn for many developers. Even if the developer is dropped into a project where a new skills are required, often they don’t sit down and learn those skills.

Thanks to the wealth of snippets and quick-fixes available on Google and StackOverflow, it’s very easy to become a copy-paste developer. Just learn the basics of your programming language, and then use the internet for anything that’s required right? – Wrong. Even if every solution you find on the internet is suitable for you and you can finish most of your tasks by searching for answers on the internet, it’s going to make you a slow developer. A terribly slow developer.

You need to be able to do most of your work by yourself without searching for answers. The internet helps in situations when you are stuck. But if you need to search for almost everything you are doing, it means you are stuck all the time. It’s like repeatedly stopping to tie your laces while you are running a race. You will eventually finish, but your progress will be slow and rocky.

Invest time and effort to actually learn the tools you are using. Your language, the core libraries and frameworks you use, your IDE, your build system – these are the things that you should sit down and learn. There is a big difference in quality, speed and smoothness when a developer actually knows how to do their task rather than searching on the internet for every basic thing.

Not Getting It Right First Time

When you complete your development and merge it with the main codebase, you should be sure of what you have done. Have you thought about all error scenarios? All possible exceptions? What assumptions have you made? Have you communicated those assumptions and ensured they are correct? Have you thoroughly tested it? (Yes, a developer is supposed to test their development before sending it off to a tester)

Ensure that the tester won’t send it back to you. Or worse, it won’t end up as a user-reported bug. Or even worse, it won’t break the production system.

Making sure that your code doesn’t have mistakes and bugs are very easy when you are still writing it on your computer. Once your code passes on to the next phase, your mistakes become more expensive in terms of time to fix it. Think about finding a typo on your computer before you commit. Versus, the time to deploy it, have the user find the issue, reporting it back, it landing as a bug on your plate, then you fix and deploy again. Carefulness on your part would have saved that much time.

Time for doing bug fixes is usually not planned into project timelines. So whenever you introduce a bug and it has to be fixed later, it will take away time from something else. Imagine you are already assigned a task and suddenly a critical bug lands on your plate. You spend a couple days fixing the bug, and your original task now has two days lesser to complete.

The timeless proverb ‘a stitch in time, saves nine’ is one of the most important things you should keep in mind. When you work on completing a task, always remember, that you should get it right the first time. Don’t depend on the tester, or the user, to discover a bug. Consider it your responsibility and comb your work thoroughly to ensure you have covered everything – code bugs, user misuse, changes in integrated systems, unit tests, error messages, breaking compatibility – everything. Only then commit.

Not Considering All Activities

When you have a task and a target date, you need to consider what the target date means. Most of the time, when an execution team gets a target date, it means the task is supposed to be completed and available in production on that date. But in developer’s mind, it often gets registered as the date on which they should complete coding. Even when the developer is told specifically that the target date is when the task should be on production, it doesn’t create a concrete realisation in the developer’s mind.

You need to think about –

  1. The time required for your code to be reviewed and merged
  2. The time required for deployment on a QA stack
  3. The time required for the tester to run tests
  4. The time required for the tester to write new tests for your code
  5. The time required for you to fix any errors discovered by the tester
  6. The time required for your code to go to a pre-production environment
  7. The time you need to wait (for safety) on the pre-production environment before going to production
  8. The time required for documentation changes
  9. The time you need to deploy on production

Those are just a few things that come to my mind. You might have more than that (or less), but the takeaway is that you must think about how many things need to be done to call your task ‘completed’. You might think there is a lot of time for you to finish your task, but it’s simply wrong to take all the time to write your code and your tester gets two hours to test before it gets deployed to production. For example, when I get 10 days to complete a task, I usually find that I have 2 – 3 days to finish development and hand over for testing.

Conclusion

Of course those are just a measly 5 factors among several others that contribute to delays in software development, but in my experience, when intentions are good and the project is still delayed, those are usually the main culprits. More importantly, as a developer, those are the 5 points that are actually in your control. Fix them and you’ll stand apart from mediocrity. Be awesome.

Benchmarking Java Methods using JMH with Gradle

JMH (Java Microbenchmarking Harness) is a library for benchmarking Java code. Running a benchmark using a library such as JMH is better than simply measuring execution time of methods using System.currentTimeMillis() or System.nanoTime().

The easiest way to run a benchmark using JMH is to use Maven/Gradle plugins. This article shows how to write and run a simple benchmark using the Gradle plugin.

I suppose you already have a Gradle project in which you want to use JMH, but if you wish to try out the walkthrough in this article, you can checkout the code from here as a starting point – https://github.com/heppydepe/measuring-execution-time-of-java-methods/tree/v1.0 which was used in the other article ‘Measuring Execution Time of Java Methods‘. It is a simple project with a class called ‘RandomNumbers’ that creates a list of 100 random numbers and stores it in memory when an object is instantiated.

Add The Plugin

The latest version of this plugin is 0.5.3 at the time of writing this post. You should probably use whichever latest version is available now.

plugins {
    id 'me.champeau.jmh' version '0.6.5'
}

Write Your Benchmarks

The plugin expects all our benchmarks are put in a src/jmh directory. I like this because it is similar to how we would keep our unit tests – in a separate src/tests folder. So create a jmh directory inside the src, create folder structure to represent your package inside this. That is, if your package name is com.example.mybenchmark, then create com/example/mybenchmark directory inside the jmh directory.

Create a java file for putting your benchmarks in. This is a benchmark –

@State(Scope.Benchmark)
public class RandomNumbersBenchmark {
    @Benchmark
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    @BenchmarkMode(Mode.AverageTime)
    public void initializeRandomNumbers(Blackhole bh) {
        bh.consume(new RandomNumbers());
    }
}

new RandomNumbers() is the piece of code that we are benchmarking. We are benchmarking the performance of creating new RandomNumbers objects. The Blackhole.consume() method ensures that JVM optimisations don’t come in the way of our benchmark. Without it, the JVM can see that we are not actually using the new RandomNumbers object, and optimise our code accordingly. JVMs do many such things and benchmarking frameworks like JMH give us ways to minimise JVM optimisations from hurting our benchmark numbers.

Run the Benchmarks

Running the benchmarks is quite simple. Just execute ./gradlew jmh from the project directory (where the build.gradle file is). You should be able to see the benchmark running and displaying it’s metrics as it runs. And the output would end with a summary like so –


Benchmark                                       Mode  Cnt     Score    Error  Units
RandomNumbersBenchmark.initializeRandomNumbers  avgt   25  2056.808 ± 84.686  ns/op

The full project for trying out can be downloaded from GitHub – https://github.com/heppydepe/measuring-execution-time-of-java-methods/tree/v2.0

Screenshot of a JMH Benchmark Running

Annotations

There are a ton of annotations in JMH which you can refer to in the documentation. But I’ll briefly write about the annotations used in the above sample.

@State is used to assign a “Scope” for the benchmark. Possible scopes are Benchmark, Group and Thread.

The @Benchmark annotation identifies this method as a benchmark. Similar to the @Test annotation that marks Unit tests.

@OutputTimeUnit annotation specifies what time unit your benchmark output should be in.

@BenchmarkMode annotation specifies in which modes the benchmark would run. Note that this annotation can supply multiple modes. Possible modes are AverageTime, SampleTime, SingleShotTime, Throughput and All.

For reference, all annotations and their meanings can be found in the JavaDoc for JMH.

Why JMH?

Microbenchmarking is a big step above simple time capturing. JMH does things like warmup, iterating and managing threads for us. It also helps us avoid common traps while benchmarking – for example, side stepping from JVM optimisations so that our benchmarks are accurate.

Picking My Game Development Tools

A process that used to excite me during my early days of development is to choose a tool or framework. But now as an experienced developer, I realise that’s probably the most exhausting yet not very useful to spend a ton of time and energy to make difficult choices at the beginning of a project (or in this case even before getting started with the project). So I will put my thoughts until lunch today. Make the quickest decisions that I can make. Stick with till I’m good.

Guiding Principles

  1. I have to first learn a boatload of things. And it is yet to be seen whether I will stick to my commitment or I will get tired and give up. So
  2. This is a last time I process this choice. Before I complete my first game, I will not go back on these decisions. If I don’t get some feature I need, I will sacrifice on it rather than think back and change these decisions.
  3. Whenever possible, learn the art first. Invest money in tools later.
Photo by Jo Szczepanska on Unsplash

Time

The most important and difficult to get resource is going to be time. I have no intention of quitting my job and doing this full time. So my schedule would be to utilise the weekends and holidays to the fullest. It’s been very long and I have about a ton of gaps in knowledge to get where I want to be. So I don’t expect I’ll make anything significant at least for a year or even two. I’m also currently studying for masters, which will go on for one more year. So for one year this will be in the third priority. I can pickup a bit more speed after that. Strictly keep this to the weekends.

Hardware

I have a 13″ MacBook Pro 2015 and a 1080p monitor. I also have a Wacom Intuos drawing tablet too, in case I need something more than my Logitech Trackball mouse for drawing. I will purchase a small – maybe 25 keys – MIDI controller for making music. But only after 3 months. If I’m still going strong. Until then, I think I can simply use my computer keyboard to learn basic music composition. Decision here is that I already have everything I need. After 3 months, I will invest in a MIDI Controller – Akai MPK Mini MK3

Artwork

There wasn’t much questions here. Blender was the straightforward choice. But I need to learn to use Blender. Making 3D models can be considered my weakest skill in this whole endeavour. I practically do not know anything about it. I learnt some 3D modelling 20 years back (on a tool called Gmax – which has been discontinued now). I’m not sure whether I will remember anything or whether that knowledge will be useful now. I don’t think I will have to upgrade in future even after I become a good 3D modeller. Both Blender and Sketchbook are great tools even for professionals. So they should be good enough for me. So Blender and Sketchbook for artwork.

Music

There weren’t any good open-source music making software. I found LMMS, but it was far behind any decent commercial alternative. Almost nobody on the internet recommended it for a beginner. But fortunately, since I use a MacBook, I have GarageBand and it’s free. I will learn the basics of music composition and then upgrade my setup to a 25-key MIDI controller and FL Studio. I checked out another software called Reason – which appears to be great, but for a higher price. But in terms of popularity, FL Studio came out as a big winner, and so I believe as a beginner, it’s better I use FL Studio since I’ll have to be asking help from the community a lot. So decision is FL Studio.

Game Engine

A quick search on the internet showed me that I have two options Unity and Godot. I did some time-consuming research, before coming to the realisation that Unity is free-to-use. I don’t have to worry about its cost unless I am making significant revenue, which I don’t t think I will be making anytime soon. If you are making that much revenue, Unity’s licensing costs wouldn’t seem much. And Unity also didn’t appear to me as an evil company that would irrationally jack up license costs. So Unity it is.

So there. I have a big set of skills I’ll have to acquire in the next several months. Let me get cracking.