My First 30 Days at Atlassian

On February 21st I let my (former) employer know that I was resigning because I had taken a position at another company to grow professionally and expand my technical abilities. Come April 1st I started a new position as a Junior Backend Developer at Australia’s best software company (IMO) and one of the world’s best software companies (IMO), Atlassian. I was going to write this post a little earlier but I wanted to get more settled into my new position at Atlassian and get a better feel about how I was really adjusting working at a new and amazing company, in a new city, with me not knowing anyone at the company. What I can say it has been fantastic 😀

Previously my commute was a very short walk to the bus stop, then catching the free shuttle bus service our town offers to work (which was the bus’ first stop from where I caught it from). In total the entire trip from my house to my work was generally no more than 15 minutes at the best case. Now I need to wake up early (well early for me) at around 6am, drive to the train station and catch an early train to the Sydney CBD. I could catch a later train but there is no guarantee that there will not be any diversions or delays. In total the trip can take as long as 1 hour and 30 minutes. Thankfully I don’t need to stress on the train trip as I don’t need to change trains (the one I take directly goes to the CBD), can do some light work, listen to some music or a podcast, and even chat with my mates if they catch the same one that day.

One thing I can definitely say is that Atlassian looks after their employees very well. Originally for breakfast I would have an Up & Go and then head to work. Now I don’t have breakfast at home. Atlassian offers free breakfast 🙂 I usually grab a bowl of fresh fruit and yogurt, and a small bottle of orange juice. Overall a much healthier breakfast option. For lunch I would generally make myself a sandwich and pack some snacks like crackers, yogurt, muesli bar, etc. Again, I don’t need to worry about lunch because Atlassian has me covered with free lunches everyday. With an assortment of different fruits, vegetables, meats, breads, drinks, etc and hot foods on Tuesdays and Thursday I can safely say that I will never get hungry; oh that is not to mention the assortment of snacks including chips, biscuits, nuts, ice cream, etc. I have already started to put on weight that I need to work off with all the food I am consuming.

One thing that I knew was coming was getting a new Apple laptop, based on all the images I saw of employees with their computers on Glassdoor and YouTube. I have never owned an Apple product until now and I am still getting used to the butterfly keyboard and macOS, but generally moving between Windows and macOS is no different than when I was moving between Windows and Ubuntu at university. On the hardware and workstation front having a super comfortable computer chair, standing desk, and large monitor along with a Macbook Pro that is spec’d out to the gills are all great things to have. If you are in Silicon Valley or work at a startup technology company these might all be common but it wasn’t where I was previously working (including the amount of free food and drinks).

Working at Atlassian has also been amazing so far. I am on the Bitbucket Server team and it has some really intelligent and talented developers, designers and managers. One thing that I have noticed when I got here was that my team and manager had a plan for me for the next several months and if I had any questions I could approach any colleague whether they were or were not on my core team. After getting through the massive amount of HR and onboarding tasks put in front of me there was just so much to learn. Many at the company say it is like “drinking from the fire hose“. There is just so much to learn, consume and understand. I can say that what they are saying is 100%, based on how much there is to learn and consume. Thankfully for me, I am surrounded by such helpful people that if I need any clarification or guidance about anything I can easily approach them and they are more than willing to help. It can be a little daunting to try and understand everything, see how everything fits together and how to resolve some of the issues. But as any good developer would say, your debugger is your friend as well as the log files. With a very clean code base with plenty of unit and integration tests it makes understanding the product much easier.

To summarise my first 30 days, it has gone very quick. From fun company and team events such as Star Wars movie event for May 4th (we had it on May 3rd as May 4th in Australia is on Saturday) and lawn bowls to resolving customer issues on Bitbucket Server, I have completely enjoyed my time. I am always learning something new every day and am trying to help my team as best I can, where I can. The next couple of months I am going to try and resolve more and more complex problems, try not to break anything (or if I do fix it) and ensure that I am leaving a positive measurable change. One thing I have learnt very quickly is to speak up when stuck, if you see an issue don’t ignore it but proactively do something about it. Everyone at the company I feel breathe Atlassian’s company values. With everything going well so far, I hope to be here for a very long time.

If you are looking for a change the take a look at the Atlassian careers page, we are always looking for talented individuals to grow our ever expanding team.

Returning back to the fundamentals and my programming roots

I have been at my current employer now for over four years and when I started there I was merely involved in the implementation of new features and bug fixes. But as my tenure increased as did my involvement in the projects that I was implementing for the various customers we have, and responsibilities. Now I spend a significant portion of my time not looking at as much code or configuration for the project’s implementation but assisting my team members in implementing new features or fixing bugs, helping our customer support team resolve issues, working through customer requests with a business analyst and how it could be implemented, and ensuring that we meet the deadlines that we have set.

Moving from a software engineer to a manager like role is different and presents its own set of challenges. The code I do look at now and modify is mainly to assist another colleague (pair programming, guidance, etc), to optimize what we currently have (nothing better than making something run more efficiently or take up less memory), or to streamline our internal development process across the teams (if I can automate it then why not). I really do miss sitting at my desk uninterrupted for extended periods of time listening to either a podcast or music and coding away resolving a bug to be ready for a release or implementing a new feature for a customer. But now that is few and far between.

With this limited amount of time programming at work I have decided to start programming even more at home; I really don’t want to get rusty at my programming skills. The last month or two I have been attempting to (and successfully) solve programming challenges and problem sets on both LeetCode and HackerRank. Both are very good sites IMO on keeping your software engineering skills up to scratch and making sure that you understand the fundamentals no matter the language. Along with this I have started to get back into working on some side projects. The problem I have with side projects is that I start them, get a portion of the way through them, and then lose interest. I have many side projects shelved and stashed which are incomplete, and when I go back and look at them I know why I stopped working on them; to be honest they are not really good side projects.

So for 2019 (and I have been going strong so far which is really why I have not written a meaningful blog post recently) I plan on working on and finishing a side project (at least one meaningful one) so that I can showcase it, and write up some more technical post about what I have been reading and doing in my spare time. 2019 is going to be another good year 🙂

Portrait or Landscape Monitors when Programming

Recently we moved to a new office and I decided to change the orientation of my primary programming monitor from landscape (the default way you would see a 16:9 monitor) to portrait. Another colleague of mine had done this some time ago and I asked him how his experience was programming like this and he enjoyed it. I have also spoken to a couple of other individuals who have also recommended it. After trying it out for over three weeks I am really enjoying the orientation of the monitor as well.

There are a couple of reasons why I feel that changing your primary programming monitor from landscape to portrait is beneficial. These include:

  1. Writing “better” code – now when I mean “better” code, I do not mean more efficient or optimised code. What I mean is code that just plain looks better and is easier to understand and ready. In IntelliJ (the primary IDE I use at work) there is a right margin or hard wrapping guide that is displayed by default. I tend to write code that does not cross this line anyway, but having code that flows down and not across the screen I find is easier to read. Plus it forces you to think long and hard about how you structure your methods and what they do. For example, you cannot have too many nested if statements, for loops, etc. because if you do your entire method’s body is slowly getting shoved into the middle of your IDE. It certainly will cross the margin and wrapping guide, and if you have your monitor in portrait mode it becomes difficult to read the entire method’s content without scrolling horizontally.
  2. More code – not only is there “better” code written, but you get to see more code. When I am creating classes and methods, I tend to think about how they should be constructed, and what they should have in them. Typically they do not bloat out to more than one thousand lines of executable code for a class for example. If they do then I need to rethink what is actually trying to be implemented and potentially refactor and restructure the class (and/or classes) better. Being able to see more of the methods used in a class, etc. can be super helpful when trying to work within a class that needs to be refactored or have new methods added to it.

However with these some of these benefits that help improve the structure of your code and what you see, there are some pain points and frustrations that may arise which can be fixed or mitigated. The main ones are:

  1. Your IDE tabs – these include such things as your Project tab, Structure tab, your Maven Build tab, etc. By default these tabs sit on the left and right hand side of your IDE (for IntelliJ by default anyway). If you are a fan of keeping these open (I am not) then you will lose even more real estate to write code. But you can either move them to the bottom bar where generally your Terminal, Output, Debug, etc. tabs are stored or you could even pop them out to a new window. I generally tend to move them to the bottom but I have had them floating as separate windows as well. Both options work with minimal issue.
  2. Horizontally written code – not all the code you will see in a project’s repository will strictly enforce the use of the right margin, especially old and legacy code. Sometimes you will see code that requires you to scroll even if your monitor is oriented in horizontally, this I generally find will come in the form of the parameters passed into a method (the method should probably be refactored as it most likely is doing too much with too many things) or there is a long block of string that has no break. Unfortunately this is more difficult to fix. Methods with a large number of parameters and variables passed in should send alarm bells ringing that this method may be doing too much and needs refactoring, but you can add new lines after ‘x’ number of variables. For long strings you can keep it, but you can also split the string up. So there are solutions but will require a little work.

Overall I am fairly happy with the new switch in monitor orientation. Do you code with a monitor oriented in portrait mode? If so how are you finding it. If you moved from horizontal to vertical and then back, what did you not like and why did you switch back? Let me know in the comments below.

Software Development: On A Need to Know Basis

A good clear principle for any software engineer and developer is that any class, method or function that you create and use should only have the bare minimum number of necessary arguments passed into it to correctly operate and not know more about the system than it should. Recently I have been doing some merge reviews and too many times I have seen the below case from both junior and (surprisingly) senior engineers:

...
Object object = getObject();
Date objectDate = getObjectDate(object);
...
private Date getObjectDate(Object object) {
    ObjectReader objectReader = new ObjectReader(object.getId());
    return objectReader.getDate();
}
...

As soon as I see the above I leave a comment on the merge request, something along the lines of “Why does the getObjectDate(Object) method need to take the entire object instance?“. This then forces the one who submitted the merge request to stop and think what is being done, and should it be refactored in someway.

In this case, the method only uses the object’s id to build a reader and get the date from the object. The actual object is not being used at all. Instead of passing the entire object into the method the id should only be passed in. There is less overhead. We should be seeing something like below:

...
Object object = getObject();
Date objectDate = getObjectDate(object.getId());
...
private Date getObjectDate(String objectId) {
    ObjectReader objectReader = new ObjectReader(objectId);
    return objectReader.getDate();
}
...

By only passing the bare minimum to the methods or classes then you are ensuring that your system does not know more than it needs to. By enforcing this rule, IMO you are ensuring that the system is:

  1. Cleaner – you know exactly what is being used and for what purpose.
  2. Safer – you are ensuring that only what you want to be manipulated can be manipulated and where.
  3. Modular – there are clearer separations between what needs to be done with what and where.

So when you are creating new classes or methods then consider what you are using as your arguments, what the method needs to do, and what exactly you need to pass in. Taking the time to logically structure your code and think through what is necessary for the method to do its job will save you massive headaches in the future. Short term pain, for long term gain 🙂

Moving to Visual Studio Code

I performed a clean install of Windows 10 on my Surface Book 2 recently and I have not installed my default go to Java IDE, which is IntelliJ. Instead I have now moved to using another tool, which I am finding is much more versatile and beneficial; Visual Studio Code. I have previously used Visual Studio Code but mainly as a way to edit my various data files such as XML, XAML, JSON, etc. and not any of my source code files like Java, C# or C++. I treated VS Code as a text editor only previously.

Visual Studio Code comes with a crazy amount of extensions which is great because that gives you options. To get started with Java, the extensions that I suggest you get is:

  • Java Extension Pack – this comes with all the necessary Java dependencies for Visual Studio Code such as proper language support for Java, Debugger for Java, Java Test Runner, Maven for Java.

On top of that extension you will need a JDK installed. If you want to know how to setup the environment for Java then have a look at the comprehensive page that Microsoft has created here. Microsoft also has a pretty sweet tutorial about how to build a Spring Boot application that can be found here.

One thing that IntelliJ made super simple was the compilation of Java code and managing all the dependencies, not to mention providing some really convenient debugging tools and project management. This makes it a really powerful development tool. When I was at university I primarily used a terminal or command console with a basic text editor for developing software, but as I moved towards writing commercial software for the company I work for I relied less and less on the terminal and command console and more on the IDE for the heavy lifting. Now that I use VS Code I am using the terminal and command console more again, and all of the necessary information such as the class path, dependencies, etc to ensure everything complies correctly is critical. Looking at this now, I really appreciate what the IDE does to simplify development process but realise how important it is to know the fundamentals.

I wrote about a similar scenario a month or so ago regarding Git (this can be found here) and how important it is to actually be really familiar with the Git commands through a terminal and/or command console because it is cross platform but it allows you to truly understand what is going on. Using a GUI is fine but all that does is issue the same commands you would use if you were using a terminal or command console. Using VS Code and the terminal to compile and execute my Java applications has allowed me to really appreciate what the IDE does to simplify the development process but also familiarise myself with the fundamentals and important concepts that can be carried between platforms.

 

Software Development: Writing Better Code Through Code Reviews

One of my favourite parts about being a software engineer is reviewing code. You get to learn alot about an individual from the code that they write and also learn how to potentially do something more efficient or understand a component of the application you had little exposure to before. If I look at a merge request, within the first few lines of code that is submitted I can get a good sense of how many years they have been programming and if they know what they are doing or if they just copied and pasted something from StackOverflow.

Graduate software engineers, entry level software engineers, or individuals who have just started programming, will often leave out some crucial elements such as appropriate null checks, logging, comments or appropriately named classes, methods and variables. There is nothing worse IMO then looking at some code and seeing a variable named “numbers”. It is most likely some collection object like a List and contains numerical values but offers little context in respect of the application it is used in. It may make sense to the person who wrote it but it probably won’t to others and you will most likely forget its context several months down the line. Red flags are very easy to spot here.

The more experience you get, the quality of the code that is submitted is generally far easier to read, is structured and broken down logically, has been optimised, there are the appropriate exceptions and null checks in place and the classes, methods and variables are named appropriately. But to get to this level you not only need to write a good amount of code but also look over and see how others are structuring and writing their code and do reading/research in your own time.

At work when I get a request to do a code review there are a number of elements I look at. Some of which include:

  1. Appropriate and meaningful class, method, and variable names.
  2. Small, compact and single purpose methods.
  3. Appropriate null and boundary conditional checks.
  4. Some level of optimisation on the operations performed.
  5. Meaningful unit and/or integration tests have been implemented.

At times I think that I am fairly harsh on the individual who submitted the code to be reviewed but then I think to myself that the better the code repository is in, the easier it will be to maintain and if good code practices are enforced then it will make everyone a better programmer. If I didn’t start being critical of my code and trying to better myself then when I do the code reviews I probably wouldn’t be as critical of theirs. Setting a high standard will only make the lives of software engineers working on the project much easier in the long run even if there is short term pain.

Artificial Neural Network: The Neuron

I am by no means an expert in machine learning or artificial intelligence, but just an avid learner and curious individual. Please use the information provided here as a supplement to further your knowledge and research.

I am currently building an artificial neural network from scratch (more specifically a multi-layer perceptron neural network. To help clear my head and make sure I understand everything correctly (or still remember from my machine learning subjects at university) I will be writing several blog posts about machine learning and artificial neural networks. To start the list of blog posts off I am going to write about one of the fundamental building blocks of the neural network, the neuron.

I will be skipping the background about the neuron and how it relates to the biological neuron. Instead I will cover how it is constructed and used in an artificial neural network.

Inputs

The neuron will process inputs from the previous artificial neural network layer. The previous layer could be:

  1. The input layer of the artificial neural network. In this case then the values are taken directly from the training data, test data, or user input when using the trained artificial neural network.
  2. A hidden layer of the artificial neural network. In this case the values would be outputs from other neurons.

Note: There is a special input which is called the “bias” which always has a value of +1. The role and purpose of the bias is so that there is a trainable constant and allows the activation function (will talk about that a little later) to give us the best possible chance of an optimal model. You can read some more about the bias purpose and use here and here.

Weights

For every input to the neuron there is an associated weight. Initially the weights are generally given a random value between the range 0.1 to 0.9. As the artificial neural network is trained the weights are adjusted as to better match the desired output.

Operations

Summation

The first operation to obtain the neuron output is to perform a summation of the multiplication of the associated weight and input. Mathematically this is represented as follows:

 

Artificial Neural Network Summation

 

where:

  • y is the output.
  • n is the number of inputs to the neuron.
  • i is the index of the input to the neuron.
  • w is a weight.
  • x is an input.

You may be asking, Chris why do we have the zero indexed weight and input outside the actual summation when you just add it anyway? Good question reader. Generally the zero indexed input is the bias which then makes the associate weight the zero indexed weight.

Activation

After the summation operation is performed there needs to be an activation function used. The use of the activation function allows for the enhancement or simplification of the neural network. Generally the activation function is non-linear and there are a variety of functions that can be used. Two of the most common activation functions are either sigmoid or rectifier functions. More information about the sigmoid function can be found here. More information about the rectifier function can be found here. The final value of the activation is the output of the neuron.

The next blog post would most likely be about the various layers of the neural network and how they are all interconnected. So stay tuned.

Git. Command Line or Graphical User Interface?

I was doing some reading today about Git and whether software engineers (or anyone else for that matter) should learn to do all their changes, etc for Git using command line or a graphical user interface. It was an interesting piece and some valid points were made for both using a command line and/or a graphical user interface. Me personally, I use a graphical user interface because it is extremely easy, hooks directly to the Git commands (under the hood) and can give you a nice visual tree of what the repository looks like. For your information Sourcetree is the client I use. However the more programming and development I do, the more I appreciate and want to learn what, how and why.

Some of the reasons why using the command line approach is valid and well worth it include but not limited to:

  1. Platform Independence:
    • No matter what operating system you are on, the commands are universal. So if you can use the Git commands in a Linux environment, then you will have absolutely no problem whatsoever doing it on a Windows or MacOS machine.
    • Git clients like Sourcetree for example are not available on every platform, and I imagine the other Git clients are also not available on every platform.
  2. Understanding:
    • This fundamentally for me is important and I think should be high on everybody’s list when using something.
    • By using the command line you get a level of understanding of what exactly you are doing, whereas using a graphical user interface this level of understanding (well to me) is abstracted and partially lost.
    • It also comes back down to point 1. If you understand what you are doing then you can take it to any platform.

Now using a graphical user interface is not the end of the world. Sometimes you just want to get something done and using a terminal if you are not comfortable with it can be extremely daunting. I personally would never be caught dead (well right now anyway) resolving merge conflicts and looking at diffs using a command line, and rebasing using a graphical user interface is so much easier.

I did some quick Googling and found what I feel are two really good resources that help and ease you into using the command line for Git. There is Try Git and Learn Git Branching. There are probably more out there but those are the two that I felt provide a good starting point. If there are others out there that you use or feel that there is a resource that is definitely worth reading then please add a comment below (sharing is caring) 🙂

Software Development: Returning Null and Null Checks

This past week I was looking over a number of merge requests and some of them had new methods declared with a return type of String (these are Java classes). With all of these methods if there is a logic issue or some unexpected behaviour then instead of returning an empty String object they all returned null. Personally this starts ringing alarm bells and waving red flags. Why is that you may ask?

If nulls are being returned, passed around to other methods, etc then the programmer will need to check before using that object (well they should anyway). There have been numerous times where I have seen programmers completely ignoring a null check for an object even though the method they used before to set that object could potentially return a null. With every one of these cases I politely leave a comment on the merge request, waiting until an update commit with the null checks are added before merging. Better safe than sorry.

Now am I being too cautious? I tend to lean towards the overly cautious side because it does not take much more lines of code and effort to ensure that the appropriate logging and checks are in place so that unexpected errors and problems with the software are not encountered by the user; plus it means that the software you are writing is safer. Let me know how you handle situations like this. Talking to some of the other programmers I know, they are split on the subject. Some don’t really care what is returned and don’t bother checking the object before use (those I call cowboy programmers), some don’t really care what is returned but do check before the object is used, and some care about what is returned and always check the object before use (I fall into this camp).

Potentially this problem is solved on a case by case basis. Is there a valid reason a null object should be returned? I’ll be doing some more reading about this to get a better understanding to ensure that I adhere to proper programming etiquette and safe programming.

Git: GitHub & SSH Keys Setup

I have generated an SSH key a number of times, either at work or on my personal PC for a number of accounts. Now that I am using my Surface Book 2 as my primary development device until I get a new SSD for my desktop PC, I thought that it might be worthwhile documenting how to generate an SSH key and add it to a GitHub account.

Now if you already have an existing SSH key then you can go ahead and use that but if you have never generated an SSH key before or you may have forgotten how to then hopefully you will find this guide useful.

Assumptions/Pre-Requisites

  1. You already have Git installed on your device.
  2. You will be using GitHub for your repositories.
  3. You are using a Windows environment.

Step 1 – Create a new SSH Key

Do not proceed with this step until you have the pre-requites met otherwise this guide will not work for you unfortunately.

  1. Open your Git Bash Terminal.
  2. Execute the following command replacing <github email address> with the email address you use for your GitHub account:
    ssh-keygen -t rsa -b 4096 -C <github email address>

    The parameters used in the above command are:
    -t rsa – the type of key to create. In this case an RSA Key.
    -b 4096 – the number of bits in the key.
    -C <github email address> – a comment or label for the key.
    For more information about the parameters that can be used click here.

  3. You will be prompted to provide a file location where to save the SSH Key. Press Enter. This will save the file in the default location. Using the default location is recommended in this case.
  4. You will be prompted to enter a secure passphrase. If you choose to provide a secure passphrase then it will secure your SSH Key, this is a recommended step.

Your SSH key should now be generated 🙂

Step 2 – Adding your new SSH Key to the ssh-agent

If you have successfully performed the step “Step 1 – Create a new SSH Key” or you already have an SSH key that you want to use then you can proceed with the following step.

  1. Open your Git Bash Terminal (if you have closed it).
  2. Execute the following command:
    eval $(ssh-agent -s)

    This will start the ssh-agent in the background.

  3. Execute the following command:
    ssh-add ~/.ssh/id_rsa

    Note: If your key is not in the file named “id_rsa” or is not in the same location then you will need to replace the value id_rsa in the command with the name of the private key file and/or the location of where the file is store. The above example is for the default name and location.

Step 3 – Adding your SSH Key to your GitHub Account

The hard work is now all done. The next part is super easy even though there are more steps.

  1. Open your Gut Bash Terminal (if you have closed it).
  2. Execute the following command:
    clip < ~/.ssh/id_rsa.pub

    This will copy the content of your public key file ready to be pasted into GitHub. It is important to not add or remove any spaces or newlines to the content.

  3. Log into GitHub.
  4. Navigate to the “Settings” page.
  5. Under “Personal Settings” select “SSH and GPG keys”.
  6. Click “New SSH key”.
  7. Add a Title to your key. In this case for me it was generated from my Surface Book 2 so I made sure that it was referenced in the Title.
  8. Paste your key in the “Key” field.
  9. Click “Add SSH key”.

You should now see a new SSH Key added to your GitHub profile.

For more information generating your SSH Key, adding your SSH Key to your GitHub account, and other SSH connection information take a look at the GitHub Help Page. I have tried to simplify the process by combining the information that was scattered across two to three pages from the GitHub Help Pages into one page. The GitHub team have done a fantastic job in documenting the entire process however and the above link should be used if my steps are not sufficient or confusing in any way.