Have you ever thought about the complexity of the technological world of a Java programmer? It’s mind-boggling. How do you manage to deal with so many tools, each and every one changing every few months or if you are lucky years? What enables us keeping up with so many new hypes, discarding the negligible and absorbing the useful? How do you manage to stay relevant, find meaning in what you do and in the same time have a healthy work-life balance? It’s mind-boggling, I tell you.
To exemplify my point, I will go through the things a Java developer needs to know or do nowadays. I tried to fit them in categories, but this was not always cleanly possible, the overlap between them is sometimes pretty large. This is another intricacy of – this time not restricted to Java – the software engineering business as a whole. You cannot just say you learned one thing and subsequently move to the next one. Your knowledge has to get wider and deeper at the same time while you constantly go through phases of theory and practice and often enough these phases are strongly intertwined.
But before I start, let me write a few words about my background. I am (mostly) a Java developer living in Germany with several years of experience in several companies in different fields. I used most of the technologies listed in this article in a more or less intense fashion during the past years, some of them I only had a superficial look into and a handful of them I only know by name (for example I didn’t have the chance yet of working with Travis CI). While I think most of the following is generic enough to apply to lots of the language ecosystems, various ones, like C, managed to remain considerably simpler compared to Java, while still benefiting from a widespread usage.
And now without further ado, let’s start. As a Java developer you have to…
Know thy language
This is an easy one. At least no quarrel is necessary about the best language out there: we limit ourselves to Java. And if you are a Java programmer, you can consider yourself lucky. Java has been around for almost 25 years now, most of which being in the TOP 3 according to the TIOBE index (most of the time being the first though). Currently (January 2020) Java still holds the first position and IMHO, it will still hold it for some time to come. I’m pretty sure Java is still going to be relevant in 50 years, although the degree of relevance will depend on a multitude of factors.
But let’s get back to the language itself. Java is before anything else a strongly typed, object-oriented language. As such, you must understand the OOP concepts when working with it: inheritance, abstraction, encapsulation, polymorphism and some more. You must know the syntax of the language and its core packages: IO/NIO, Concurrency, Reflection, Networking, Generics and several others. It’s important to know that Java uses garbage collection, and that you can fine-tune it for your needs. You need to know how the memory model looks like and which data structures are available through the Collections package and which algorithms are built in and which require the usage of some external library.
You need to know that Java is a specification having multiple implementations. And you need to know that just knowing the syntax and the core libraries without knowing the design principles and patterns will most probably get you scolded every time you present your code in a code review – and rightfully so.
Know thy design principles and patterns
Design principles and design patterns are distilled recipes for specific recurrent problems. While some principles, like YAGNI are limited to specific development methodologies, others describe best practices in the context of a programming or architectural paradigm.
So, if you don’t want to get scolded during code reviews you should know about the Gang of Four (and I don’t mean the rock band) and the 23 patterns they defined. You should also have an idea about the multitude of other more or less specific and relevant patterns existent out there. And anti-patterns are, of course, just as relevant. You should also be aware of the fact that although singleton was a perfectly valid pattern a while ago being defined by the Gang of Four, using it nowadays might trigger some very passionate reactions. And of course you should also know the SOLID principles and be able to deal with acronyms like GRASP or KISS.
The funny thing is, after a while you’ll get most of the things most of the time more or less right, so you don’t much care any more about patterns and their names or about the Liskov substitution principle. Faced with concrete problems, solutions come automatically; you can serenely focus your attention on other things, like for example the next hype. But wait! What about when you want to change your job? Chances are high that, when applying for a senior position, you’ll have to explain the SOLID principles in detail and explain how some specific design patterns implement these principles. It’s not only about doing things the right way, it’s also about communicating about them.
Know thy communication skills
The preconception of programmers being a very special sub-species of the Homo Sapiens, when it comes to socializing and communicating, still persists. While this might have had a certain valid basis a while back, it does not represent reality anymore. The interviewing context is just one of the many cases where a developer has to effectively communicate. Even in an interview, you have two developers communicating: the interviewer and the interviewee – very different roles.
A while back most of the technical documentation was done in documents scattered through various network file systems. Nowadays chances are high that your company uses a wiki. If you are lucky, the wiki will work on a WYSIWYG-basis, if not, you’ll just have to learn the markup language. But that’s okay markup languages aren’t generally that hard. It is often harder to decide what to document since there is seldom enough time for documenting everything relevant.
As a senior you will most probably have to do some presentations in front of various people, ranging from your team to some executives or customers. If you’re doing SCRUM you might even have to do this as a junior. And if the company you are working for is small enough, you will probably also have to represent it at some fares.
But these are all contexts which you don’t find yourself in every day, but you will most probably have to communicate with your peers on a daily basis. And here is where it’s important to know your design principles and patterns. And also, maybe some UML. Although there are some chances that it’s rather going to be some rectangle-based free-style drawings rather than standardized UML. But that’s okay as long as everybody knows what’s meant by your diagram. And you will also have to explain from time to time why IntelliJ is so much better than Eclipse (or vice versa, whatever you prefer), which brings us to the next important thing in a Java developer’s life.
Know thy IDE
Java developers just aren’t the kind of people who like coding in vi and afterwards compiling the files through their CLI (although there are rumors of their existence). They just don’t like it – in fact they hate it. What they want is having all their tools crammed up in the same interface a.k.a. their IDE. And usually their IDE is the best. Unfortunately, some companies also tend to have a strong opinion about which IDE is the best and impose its usage upon their developers. So chances are high that you’ll just have to use various IDEs throughout your career.
While NetBeans was still relatively hip a while ago, IntelliJ is nowadays the coolest kid around the block. Eclipse is still some sort of okayish, and as long as you use it with a dark theme you might be accepted by your fellow peers as a normal developer. I’m just kidding! Of course, Eclipse is still the best IDE out there IntelliJ is just hyped because of its fancy interface. 😉
But IDEs are just one of the many things changing now and then. You also have your versioning systems and your build tools.
Know thy versioning system
Although you’re pretty safe if you already know Subversion and Git, it might be a good bet to also look into Mercurial. And what about starting as a freshman at a company who has some ancient product which still needs maintenance, and which is versioned with CVS which was never updated from the nineties or migrated to something else because – well, because.
The good news is, that nobody really cares about the client you are using. If you are using Git you can use your favorite IDE-integrated Git client, or the command-line tools or TortoiseGit. Chances are that you will stumble across various clients during your career.
But let’s move on now to the build tools topic.
Know thy build tools
And when I say build tools, I think of both build management tools like Maven or Gradle and of build servers like Jenkins or Travis CI.
If you’re starting a new project, chances are high that you’ll (want to) use Gradle for building. But it’s often enough not about building some cool new application, but about maintaining some old piece of software using Ant with or without dependency management (welcome to jar hell). Maven was used so intensively during the past 15 years that you just won’t get very far without knowing it. Luckily interviewers and people in your company aren’t usually very curious about this topic, as long as the build process somehow does what it is supposed to do. and it does it in a more or less timely fashion you’re good.
Although there is some redundancy between what your build management tool and your build server do, they also complement each other in many respects. So, this is just one more thing needed to be known, changing constantly with the passage of time. Of course, you might be lucky, and some other team might be responsible for providing the automation environment you need, but maybe you’re not. While Jenkins is still a very good choice when it comes to build servers, maybe your organization uses GitLab, so why not use its built-in CI/CD tool? Or maybe it uses the Atlassian product suite, why not just use Bamboo? Well, anyway, happy learning.
Chances are that in 10-20 years most of us are going to use other build tools than we do today, which also applies to our development methodologies.
Know thy development methodologies
Gone are the high days of waterfall methodology, most companies are using agile methods now – maybe some form of ScrumBut? But waterfall is not dead, and the V-Model is also not dead, and the spiral model is also quite alive. And while Scrum is the most prevalent agile methodology nowadays, a whole bunch of others exist. And nowadays we do DevOps and DevTest and DevSecOps. Too bad I forgot my bullshit bingo card, I might have won. Here you can find a nice listing of Scrum alternatives (German text). The fact is, that the realm of development methodologies is probably more volatile than the technological realm will ever be, and I’m afraid it’s our social nature to blame.
Building software systems is before anything else a social endeavor. Melvin Conway formulated this observation in 1967 which became known as Conway’s Law, much cited during the microservice hype. While this has always been true, the more complex our systems get, the more people are involved in building them, the more relevant social aspects become.
In order to build great software, it’s not enough to know your technology stack and be able to identify appropriate solutions to a given problem, but you also have to be able to find out what the problem is in first place, and convince the relevant people of the fitness of your solution – but that’s communication, we’ve already had that. And it’s not enough to put a bunch of people together and tell them to perform; you have to mind their personalities and give them time to find an effective way of working together. And it’s not enough to build great software, just give your testers a bonus dependent on the number of bugs found and your great software which might have worked just fine up until then is going to become a bug-ridden manifestation of incompetence.
Having people of very different cultures in your teams does usually not make software development easier. And if these people also sit in different places scattered around the world things just might get a little more complicated.
Of course there are also the more technical aspects of development methodologies like bug tracking systems and project management tools, which change over time as new methodologies appear, as new hypes arise.
But let’s get back to some less menacing technical aspects: the operating system.
Know thy operating systems
Operating system you say? Java is a platform-independent language, who cares about operating systems? Well, there are some (very rare) cases when you should. While Java is a platform-independent language, it still relies on the operating system for running the byte code. So, should your application run on different OSs, you’d better test that, because there will be cases where you’ll have differences in behavior due to the OS.
But even if your apps run on a single OS, if you’re a Windows guy, you might need to setup your build system on a Linux machine. But at least the probability is low that there will be some utterly new operating system coming up in the next 20 years. So, if you halfway know your operating systems today, it will most probably be only evolutionary learning from there, something which is so very different with hypes.
Know thy hypes
I don’t really like saying this, but you should really, really know the current hypes. You should at least have heard of them. You don’t have to understand them, most other people also don’t, but if some executive asks you whether some currently hyped technology wouldn’t magically solve all the company’s problems, you should be knowledgeable enough of it to be convincing when trying to temper his enthusiasm. Of course, developers also fall from time to time for hypes, their enthusiasm should be also tempered.
Most hypes pass without leaving visible traces, while some are just old wine in new skins and have been around for decades. Did you know that the first car with a built-in touch display was the Buick Riviera in 1986, the technique behind the touchscreen being described some 20 years earlier? Or that the selfie stick was patented in 1983 as a “Telescopic extender for supporting compact camera”? Pretty fascinating, right? Lots of similar examples exist. The fact is though, that there still are enough hypes making it to the adoption stage, leaving you no choice but to understand what’s it all about. Of course, this applies only as long as you intend to remain relevant.
Know thy career plan
Dependent on the country you live in and the level of education you target, you’ll have somewhere between 40 and 50 years to work. That’s hell of a lot of time. So, while being busy learning the next relevant technology and observing the current hypes, don’t forget to do what keeps you interesting for potential employers. Keep networking; keep your LinkedIn and Xing profiles up-to-date, maybe you should learn some new technology even though your employer does not request it, just because it looks good in your résumé. How about setting up a blog?
And don’t forget, the ways of self-marketing are also in a constant change. Fifteen years ago, you most probably didn’t have a LinkedIn or Xing account. Who knows what we will do fifteen years from now. Fifteen years ago you probably had a SourceForge account, now you probably rather use GitHub. But everything is constantly changing nowadays, and release cycles have dramatically shortened.
Know thy release cycles
You’ve had five and a half years’ time to get used to Java 6 before Java 7 was released in July 2011. You probably waited a few years more until you decided to have a look at Java 7. And then again almost three years till the next Java major version came out. And now? Now you have exactly six months between releases. Some might have doubted this will work, but well, it does. These are rather small increments, but you’ll have some changes in every one of them. While most companies will only use the LTS releases, and some of them will even skip some of the LTS-releases as well, this release cycle creates a certain pressure to at least have a look at what Oracle is doing.
How about your favorite IDE? Eclipse wraps up a new release every three months, IntelliJ every four. Same applies for every other tool you use, be it your beloved MVC framework or your build server or one of the myriads of libraries you are using. And when two of your probably hundreds of pieces of software you are using don’t work together, you can only hope that somebody else had this same problem before and managed to solve it and that you can easily find the solution on StackOverflow. Alternatively, you can hope to find some equivalent library. If none of the two alternatives works out, you have a problem, and you have to track it down, and it can become very frustrating.
But with enough testing you can at least find quick enough if there is a problem and where it might be.
Know thy testing tools
Testing is paramount. Do it! And do lots of it. It’s worth it!
Some twenty years ago, the world was still simple, the software was mostly manually tested, release cycles where long, you had your plan-driven development methodologies. Well, as I said, life was simple. Now you have unit tests, integration tests, system tests, acceptance tests – okay, okay you’ve had these also twenty years ago, but I guess nobody made such a fuss about it. Now these are all mostly automatized. Tools like JUnit, TestNG, Gatling, JMeter, SOAP UI, PostMan are regularly used. And don’t forget the mocking frameworks: EasyMock, PowerMock, Mockito.
And then don’t forget the performance testing types: load, stress, soak, spike, breakpoint, configuration, isolation and internet testing. Phew, that’s a lot of testing, right? And then the UI tests with tools like Selenium and TestComplete.
Testing became some sort of science in itself. Since there usually is a tester around or even a complete test department, you probably don’t have to deal with most of these concepts with their subtle – yet highly relevant – differences – at least so they say. You should be aware though that they exist. And who knows maybe we’ll have a new hype in twenty years, full stack will no longer refer to the levels from the database to the interface but will also incorporate testing and deployment. Or are we already this far?
Know thy deployment
Like everything else, deployment methods change over time. New architectural styles, new technologies, new trends can prove to be game changers in the deployment field. A while ago you had your application servers and your servlet containers you would deploy your applications into. Now you still have them, but in their embedded versions, and packaged as Docker containers which run in EC2 instances. And since you want to deal with all this in an automatized fashion, you’ll use a tool for declaring your infrastructure as code. You might not like AWS one day and want to migrate your applications to Azure or some other cloud provider. Or you could use serverless and just focus on the business value offered by your application.
It’s tremendous what has been done in the past ten years in the realm of deployment. It’s a small revolution. But as these types of small revolutions happen over and over again in all sub-divisions of the software business, how do you keep up? Specialization is a partial answer, but as the stages of software development become more and more integrated and each one getting more and more complex, you have to have at least a general understanding of what’s happening. The ultimate challenge is continuous deployment, where you have everything put together, run automatically by a single team.
In such complex settings I sometimes wonder that there aren’t more security problems.
Know thy security
Don’t get me wrong, there are enough security problems, but their impact has been in most cases relatively small (a very interesting article on this topic can be found here). Nonetheless security as a discipline has gained lots of traction. The ranking of your website is influenced by whether the communication is encrypted, your browser will mark the connection as insecure if you don’t use HTTPS – security is definitely in. Since the wave of integration isn’t limited to the software engineering sub-disciplines, having everything talking to everything will rather increase the security necessities than decrease them.
At least you won’t have to deal with buffer overflows and garbage collection in Java. But of course there are other very easy ways of producing memory leaks (static analysis tools can help), and there are so many other potential problems, especially in the libraries and frameworks you use. The good news is, that you can check your dependencies automatically, the bad news is, that you have to do it, and you have, or at least should react each time the tool complains.
And while sending credentials as query parameters of a GET request was some sort of okayish ten years ago – okay, it was never okay, but it was still done – don’t dare doing it nowadays (it’s much worse than using the singleton pattern). Authentication methodologies also changed. While you could use Basic Authentication with your highly secure GET request (which might even have been proudly called REST) you’ll rather have to have a look at the much more complex OAuth2 today.
And of course, there are at least some legal matters you should be aware of, like the GDPR (and many more dependent on your field). You might argue that you don’t really care about this as a Java developer. Maybe not, but if you decide to write a blog and are interested in who your readers are, legal matters can become suddenly relevant.
And, well, you should at least have some idea about the licenses your tools and libraries are released under.
Know thy licenses
The FOSS movement has created so many great tools and libraries which are entirely free to use. Wait, what? Entirely free? Well, almost. There usually is this license thingy attached to them, which might impose some restrictions. If you’re lucky, your legal department will tell you exactly which licenses are okay, and which are not, but you might not be that lucky, so you should have a look at them, because you really, really want to use those libraries, right?
Know thy libraries
Where would Java be now, if every one of us would constantly reinvent the wheel? It definitely would not be one of the most widespread languages in the world. But this means: know thy libraries. You like Jackson? Why not use Gson or Genson? You only used the Java Date/Time API up until now? The majority of your team might decide to use Joda Time. Nothing bad in this but this means again some more learning. But compared to MVC frameworks lots of libraries are almost trivial.
Know thy frameworks
Most of the Java developers will need to use a Java framework from time to time. Currently Spring MVC and Spring Boot rule the top of most used Java frameworks, but who knows whether you don’t have to maintain some legacy JSF or Struts applications at some point in your career. At least the principles are similar.
And of course, you don’t want to deal with those relational databases directly; you’ll want to use some ORM-framework for that. Whether it’s Hibernate or EclipseLink or ORMLite, you’ll most probably have to assess each time which tool is the best for the task at hand. And you’ll most probably deal with various ORMs during your career… and with various databases. While using relational databases was the norm a while back and before that hierarchical databases roamed the database world, nowadays you have a myriad of SQL and NoSQL databases each fit for some special use cases. Whether you use PostgreSQL or Cassandra, H2 or Mongo DB depends on what you want to achieve. Chances are that after some ten years as a developer, you’ll have already used all of the databases listed here and maybe even some more.
And last, but not least, you have to know all your other stuff whatever it might be.
Know thy other stuff
And there is lots of other stuff around, which might need an in-depth consideration. You have your HTTP libraries and every now and then some new network protocol like Websockets. You have your logging frameworks and all the other tools you need for monitoring, static code analysis, code reviews and so on and so forth.
You also have to know your XML and JSON and most probably you’ll have to work with SOAP sooner or later. Having only vague ideas about n-tier architectures, REST, microservices and service-oriented architectures might be okay – at least as long as you are a junior.
You also have all the specific knowledge related to your specific field. Developing apps in Android is something pretty different from programming an embedded device or some highly scalable cloud application. Fields like GUI development or artificial intelligence also pose unique challenges and accordingly provide specific solutions.
It’s a lot, right? I wasn’t kidding when I said it’s mind-boggling how we manage to get our jobs done. But as a matter of fact, how do we do it?
The external change happens on multiple axes:
- Firstly, things which prove useful enough as to survive, will get increasingly complex over time (just have a look at Java 6 and compare it with Java 13), as new features are added, and old ones are maintained for compatibility reasons.
- Secondly, alternative approaches or just alternative tools for the same basic problem are developed, which – should they survive – tend to get increasingly complex over time.
- Thirdly, new tools have to be developed and new layers of abstraction have to be created in order to deal with the increasing complexity, which of course, increases the general complexity even further.
- And as a last point: from time to time new technologies are invented which escape the logic of the previous points but can influence them greatly (for example the realm of artificial intelligence).
And there also are all those fads which could not live up to the promises and just died out, but they are dead, so let’s not wake them up.
So how do we deal with the complexity?
On the one hand, it just takes some time to get there. Although all that I’ve listed in this article has every-day relevance, mastering or even knowing about it takes many years of practice and some just never get there.
Although the entire picture has some resemblance with erratically grown software which badly needs refactoring, the multitude of abstraction layers hides the complexities allowing at least to a certain extent for a step-by-step approach. While it is frustratingly difficult and time-consuming to understand the entire picture, mostly the level of understanding needed for “just doing your job” is in general much lower.
The fancy-named phenomenon called illusion of explanatory depth (IOED) describes the fact that we (more or less) often don’t really know what we are talking about (at least not in-depth), and are generally unaware of this deficiency as long as we don’t have to explain how things work in detail and more importantly what their implications are. So hey, let’s use microservices. And how about switching to a reactive paradigm? This illusion and various fallacies enable us to appear even in our own eyes as being more competent than we actually are, which enables us, in the absence of better strategies, to muddle through elegantly.
Nonetheless, whether you are happy with just doing somehow your job or aim for deeper understanding and continuous improvement, you’ll have to be able and willing to constantly learn new technologies and best practices and improve your understanding of the old ones as our métier evolves at an ever-increasing pace. It is not only about the language itself, but also its libraries and frameworks, databases and operating systems. It’s also about quality and security, building and deployment, legal aspects and business considerations and ethical concerns and least but definitely not last about people and about you, the individual developer with your aspirations, career goals and perception of the software engineering world.
As Dijkstra put it (emphasis by me):
Let me try to explain to you, what to my taste is characteristic for all intelligent thinking. It is, that one is willing to study in depth an aspect of one’s subject matter in isolation for the sake of its own consistency, all the time knowing that one is occupying oneself only with one of the aspects. We know that a program must be correct and we can study it from that viewpoint only; we also know that it should be efficient and we can study its efficiency on another day, so to speak. In another mood we may ask ourselves whether, and if so: why, the program is desirable. But nothing is gained —on the contrary!— by tackling these various aspects simultaneously. It is what I sometimes have called „the separation of concerns“, which, even if not perfectly possible, is yet the only available technique for effective ordering of one’s thoughts, that I know of. This is what I mean by „focusing one’s attention upon some aspect“: it does not mean ignoring the other aspects, it is just doing justice to the fact that from this aspect’s point of view, the other is irrelevant. It is being one- and multiple-track minded simultaneously.Edsger W.Dijkstra – On the role of scientific thought.
Likewise is the intention of this blog: considering details without neglecting the big picture, discussing technology while keeping in mind that there always are people behind it. And the topic? The Java developer’s world.
You might also like the following articles: