Java is has been one of the most popular programming languages for decades. The number of specialists who want to become proficient in Java is rapidly growing. Because the competition is fierce, its no longer enough to just be a good Java developer — you need to acquire deep knowledge and get familiar with many concepts to be ahead of the competition. If you’re the one who’s stuck asking yourself “What should I learn to stand out as a Java developer?”, this blog post can help you figure things out.
Java is an object-oriented language, so instead of underestimating the OOP principles, developers should make an effort to acquire a deep knowledge of the concept. Learn how to apply OOP principles when programming and gain an in-depth knowledge of object modeling, SOLID principles, design patterns, inheritance, and other concepts. These are things you should bear in mind when writing software, especially in a modern object-oriented language.
Having these concepts under your belt will help you easily build projects applying OOP principles. Many concepts are covered in some classic books that I think are mandatory reading for developers:
- “Design Patterns: Elements of Reusable Object-Oriented Software” by “Gang of Four”
- “Clean Code” by “Uncle Bob” Robert Martin
- “Clean Architecture” by “Uncle Bob” Robert Martin
- “Refactoring” (2nd edition) by Martin Fowler and Kent Beck
- “Extreme programming explained” by Kent Beck
- “Test Driven Development: By Example” by Kent Beck
The Spring framework plays a significant role in modern Java development. Spring framework components, like Spring MVC and Spring Boot, are commonly used by companies for building microservices or web apps. Developers who understand all the advantages of the Spring framework are more likely to shine in their field, turning a local Java method into a management operation or remote procedure.
If you’ve never used Spring before, the first step is to familiarize yourself with essential Spring things, like the principles of Dependency Injection (DI), Inversion of Control (IoC), and Spring MVC in general.
The next big milestone is definitely Spring Boot and the capabilities that it brings to the table for building and running web apps. Learn the main important annotations it provides and their behavior, and consider Spring annotations in general (especially if you come from a more XML-based background).
Such ones as @Repository, @Service, and @Controller or @RequestMapping will become your everyday buddies. Try to build a small web app using them. Of course, for this learning, you need a good understanding of design patterns and how the components these annotations define are supposed to interact with each other.
You will be surprised how easy it is to launch and run your newly created application with Spring Boot, compared to other deployment options you may have used with Java before. This framework is designed to simplify your life enormously and allow you to just obtain a runnable “all-inclusive” .jar file, which you either can run from the command line on your computer, from a Docker container, or deploy as a normal Linux service and put it behind Nginx if you don’t use Docker in production.
The next Spring component which you will definitely want to learn sooner rather than later is Spring Security. Everything you need to set up proper access to your endpoints and service in general, authentication and authorization, login, registration, and different security providers, you will find there.
Another pretty big component you also can come across on quite a few projects is Spring Data. It provides a convenient and elegant abstraction for data access. It is not an ORM per se and not a JPA implementation — it just provides a versatile abstraction on top of it, allowing you to reduce the amount of code needed for data manipulation, and make it straightforward and supportable.
Finally, a component worth mentioning explicitly (don’t forget that the whole Spring is huge) is Spring AOP (Aspect Oriented Programming). It provides a way to include various annotations to control declaratively multiple aspects of your code behavior, such as logging, exceptions, or transactions. Understanding this philosophy and approach will give you a boost at any job interview.
There’s no doubt that Spring is a big fish in the Java world, but it’s not the only one. Not every Java developer wants to submit to total Spring dominance — some want to be specialized in different technologies and go deeper in different domains. For these developers, I would distinguish Java EE stack. Although old, it is still around, especially in older, large projects.
APIs and libraries go next to Java frameworks, so it’s important to know them if you want to stand out. They are an integral part of the Java ecosystem and have the second biggest community on the StackOverflow Q&A website.
This is an enormously broad topic that includes many things at once — I could dedicate a dozen of articles to it — but speaking in general, in-depth knowledge of the core APIs, main and third-party libraries, as well as Java Development Kit (JDK), defines a high-skilled Java developer. To prevent confusion, I should say that the specialists are not expected to learn all possible APIs and know every single element in the Library. It’s enough to have a clear understanding of Apache Commons, Guava, Maven, and a few other major APIs and libraries.
Recently, the Java developer community witnessed the release of the last version of Java 15. However, the software development flow in the Java domain is usually pretty slow when it comes to adopting new versions of anything — the principle “if it ain’t broke, don’t fix it” is especially embraced in enterprise projects.
Every small change happening in those projects has to fit with high-security requirements and it is common to use older technologies. For instance, in the bank, airline, or insurance system, you are unlikely to meet any technologies younger than five years or so. This is where older means stable, reliable, and secure.
Nevertheless, new versions are getting slowly but steadily adopted in these domains too. After every new release, more and more companies will require you to be familiar with the new features. Java 8, which was a big breakthrough for its time, took a few years to become an industry standard. You definitely “shall not pass” any longer without mastering the Stream API, default interface methods, Lambda expressions, Java Time API, and other major features of this version.
Further Java versions kept up the journey of the active feature adoption. The next LTS version was Java 11 — this is the one you may often meet in job requirements these days. Many companies won’t switch from it until the next LTS is released, which is supposed to be Java 17 coming in September 2021. I definitely don’t recommend you start your job hunt before getting in touch and familiarizing yourself with all of Java 11 features.
The later Java versions, up to 15 as it was mentioned above, are still to some extent or other in the process of gaining wider adoption, but they’re already in use quite a bit. For example, there is already an Amazon Corretto 15 release available.
Either way, an important practice for a good Java developer is to follow every new release very attentively and get familiar with all the new features promptly. None of them can be ignored.
Java doesn’t exist without JVM (Java Virtual Machine). It’s a runtime engine that allows Java apps to run on any possible platform. So, if you want to join a group of good Java developers, understanding the principles of JVM work is a must. Other than that, the knowledge of a virtual machine will help you with problem-solving during development. So, among other things, make sure to master JVM system threads and the way Java is executed in the runtime environment.
If you want to stay ahead of many other Java programmers, you should pay special attention to different methodologies. First of all, get familiar with Agile and especially SCRUM, but also understand Waterfall and get ready to work with it. As long as many developers select the methodology depending on the clients’ preferences, knowing many of them will help you be on top of that.
Additionally, you can learn extreme programming techniques (the classic book by Kent Beck is mentioned above) to gain richer experience and effective work.
The thing that distinguishes a real Java developer from someone trying to look like one is the ability to do automated testing. In simple terms, any kind of testing which is not manual can be considered automated: unit, integration, and others, which need to be improved if you want to be a great Java coder. You should also learn how to deliver projects in such a way that the tests are a part of your CI/CD pipeline and the code doesn’t go to production if some important parts are not covered by tests.
Here’s how your development and further deployment flow could look like with testing.
You develop a component of your application and cover it with unit tests until proceeding to the next one.
If you follow this practice thoroughly, you may notice how it implicitly forces you to keep good modularity of code. A good unit test is something that allows you to run your component’s code in isolation. You cannot use the database, external APIs, or rely on other classes. Only your component is on the scene at the moment.
You feed it with demo data that you put together accurately, taking in mind all the edge cases like empty or null values and you check that you get the output exactly as expected. After doing that, you can be sure that your component is not a source of failure and you can just rely on its logic in other places. JUnit 5 and Mockito are your best friends here — master and use them every day.
Also, another advantage is using TDD when you write your test cases and tests even before writing the component code itself. Here’s an interesting story about how much debugging time can the TDD save you sometimes.
After all the components are developed like that, you need to provide automated integration testing.
In most cases, that just means leveraging your application programmatically with a simple script, running it with some input data, and controlling the output (you will often do this in a Docker container). However, sometimes it means testing separate components or a chain of them, but this time using real external resources like database or file storage.
Either way, think about what input edge cases you can have globally and check whether your app can handle these cases correctly.
Finally, you should embed the tests into your CI/CD pipeline.
A classic modern way is that once you submit your code into your Git repository, either on commit, pull request, or merge to a specific branch, a Hook is fired. This runs a deployment script and leverages a Docker container, which tries to build your app, or a Docker image with your app, depending on your deployment.
Either way, given that the app was built successfully (and you automatically get protected from broken apps in production if it wasn’t), it tries to run all your tests within the container, both unit, and integration. If any of the tests fail, the whole process fails, and Git does not approve the pull request automatically or just fails your build.
Some details of this flow will vary, but in general, this method of app delivery will bring you unambiguous quality control literally on a per-commit basis, saving you hours of firefighting when your app crashes in production.
Coding is mainly about practicing. No matter how many books you read, they won’t be as effective as if you had honed your knowledge in practice. Fortunately, coding these days is not that boring as you may think — there are many gamified platforms on the web to make coding engaging and even fun.
Among a whole lot of platforms and courses, I would recommend considering the following.
Learning Java by doing is what CodeGym strongly recommends. Right after joining the course, you will be forced to complete over 1200 hands-on tasks and hence write lots of code. Thanks to an instant verification option, you will have your code reviewed by a virtual mentor so that you know what to improve. You can also join the CodeGym community and communicate with other students sharing your thoughts about practicing Java on the platform.
Codewars has been created by community members to let newcomers master over 20 programming languages. The learning is designed in such a way that the students polish up their skills by training with other developers on challenges called kata. As soon as the learners complete every next task, the platform rewards them with honor and ranks and sends you more advanced challenges. Here, at Codewars, you can also build your own kata and ask your peers to resolve them.
Unlike many other programming courses, Cyber-Dojo encourages the newbies to focus on improving their skills rather than finishing the game ASAP. Here, you can practice Java individually or join the group session, or even participate in coding sparrings if you already have a technical background.
Put CodeChef on the list if you are keen on coding contests and challenges — this is the perfect place for that. The platform hosts programming contests every month where developers from the whole world show off their skills and try to win trophies. Other than participating in challenges, you can also brush up on your knowledge by joining training sessions related to different technical topics, such as binary search, algorithms, array size, etc.
Codingame is an ideal learning platform for developers of all skill levels. You won’t feel bored while practicing Java — the course offers coding quizzes, solo and group challenges, a 5-minute coding battle in Clash of Code, as well as bot programming competitions for advanced developers.
Following these tips will help you stand out and join the group of great Java developers. If you know something I haven’t mentioned, feel free to share your thoughts in the comments below.
Previously published on Better Programming.