Andy Crouch - Code, Technology & Obfuscation ...

The True Cost Of Junior Developers

Photo: Unsplash - Free To Use Sounds

Not long ago I wrote about developer labelling. One of the ongoing things I have been thinking about is the cost of promoting junior developers. In the case of this article, I am referring to developers in their first or second programming role.

There is a cost with junior developers that you do not immediately appreciate. When you hire them you undertake to invest in training and in time.

Investing in training is an obvious win/win situation. You support the developer to learn and develop professionally. You also ensure that they have the skills and knowledge they need to be proficient for your company. You want good clean code developed to your expected standard. You also want your developer’s coding confidently. You don’t want them spending excessive hours on Google or Stack Overflow looking for solutions. As an unexpected bonus, I have discovered a positive side effect of training juniors. They share their newfound knowledge through conversation and at stand ups. This knowledge sharing can reaffirm other developers knowledge. It can also trigger conversations about improvements and standards within the team.

The total time invested is a cost that you may not appreciate at first. When a junior joins your team they will take time to get up and running. They will need support from the more senior team members. This means that those more senior team members are less productive. The junior developer’s own productivity will increase over time as their knowledge grows. Planning and estimating has to be adjusted for the junior’s capabilities. This all results in financial cost.

The benefits of hiring a junior developer on a lower salary can be offset both financially and in productivity.

So why when they ask for a pay rise, do we say no.

At some point, after the first couple of years, the junior developer becomes an established developer on your team. They know the product well. They have developed their skills and their productivity is high. They are clearly an experienced resource. They sit in a review and you give great feedback and then they ask for a pay rise. You have no room to pay the kind of increase they ask for or deserve. You haven’t budgeted for this. The company can not afford or does not agree with giving large pay rises. Three months later the developer has left for a company that will hire them at the salary they deserve. Demand is high for developers don’t forget, there are not enough of us.

On average at present, if you hire a junior developer, you will pay around £10k less a year than a mid-level developer. So when you have to replace your developer for a new junior you are going to incur costs such as:

  • Unless you work for a large company, you or one of your team will sacrifice time to go through a hiring round to fill the role.

  • A recruiter fee. If you are lucky enough to get 15% rates then this could be between £2.5k and £4.5k. (If you are not getting 15% rates at this level then you need to work on your recruiter relationships.)

  • You will invest in training.

  • You will invest your senior teams time in on-boarding the new junior and supporting their learning of your codebase.

  • You will lose productivity in the team as you return to having a less productive resource.

If you could and did sit down and calculate the monetary value of the points above I suspect you’d be surprised at the cost. As a leader, I would sit back and weigh up if this cycle is cost-effective against a £10k raise.

There is a flip side to this argument. As a junior developer at the start of my career, I could see the number of roles reduce if all teams did consider the arguments above. I would also argue that as a more junior developer, working for many types of company and across many projects is beneficial to your career. So it might be that even if your current role does offer you the money you deserve as you progress your career, you should still move on.

Like my previous article on developer labelling, this is really just a brain dump of thoughts. If you would like to discuss or have thoughts around this them please contact me via twitter or email.

Using SSH Config To Manage Connections

Photo: Unsplash - Tracy Adams

I have been working across many new projects recently. This meant working with a myriad of new services and servers. As the majority of these are AWS and Linux services I have found myself living in ssh.

ssh is a secure shell which provides a method of logging into another machine remotely. It supports many authentication mechanisms and encrypts traffic between machines. It is a much-preferred alternative to FTP or telnet.

You connect via ssh by passing arguments that specify the user, the machines address and the port.

$ ssh -p 22000

Security can be handled by either public/private key authentication or by a password. If the later then you will be asked for the password. Key-Based authentication works by generating private and public keys which authenticate a user. One key is stored on the server and the other key is supplied by the user when logging in. Authentication by key is an article by itself and there is a lot on the internet already. This is a good place to start.

AWS EC2 Linux instances use a key-based authentication approach. As part of the set up process you will be asked to create or select a key pair to access your instance. Once created (or selected) the public key is added to your EC2 instance. You need to download the private key to your local machine which you can do by navigating to the Key Pair menu in EC2.

Once you have your .pem file containing the key on your local machine you need to change its permissions. This has to be done as the file needs to be read-only. You can set this by doing the following:

$ cd ~/path/to/private-key-file.pem
$ chmod 400 private-key-file.pem

Now you can connect via ssh to your instance. Start ssh and pass the path to the .pem file, the user name to connect as and the public dns address of the instance:

$ ssh -i "~/path/to/private-key-file.pem" username>@public.dns.address.of.the.server


$ ssh -i "~/ssh-key-files/private-key-file.pem"

(and yes that is a fictitious DNS address!)

Now you can connect to your instance but that is a lot to remember and a lot of typing. What would be great is if there was an easy way to prevent typing. “What about an alias” you say?

alias ssh-my-ec2-instance="ssh -i "~/path/to/private-key-file.pem" username>@public.dns.address.of.the.server"

You could do that but ssh offers it’s own easier way to do it, the ~/.ssh/config file.

The ~/.ssh/config file is not automatically created when you install ssh so you might need to execute the following:

$ touch ~/.ssh/config

Once done open the file in Vim (or whatever you use) and create an entry that follows the following format:

Host <The Name You Will Connect With>
  HostName <The Public DNS Address For The EC2 Instance>
  IdentityFile <The Full Path To The Private Key File>
  User <The User Name To Connect With>

So to replicate our entry from earlier

$ ssh -i "~/ssh-key-files/private-key-file.pem"

You’d add

Host my-ec2-instance
  IdentityFile ~/ssh-key-files/private-key-file.pem
  User auser

Save the file and you will be able to connect with

$ shh my-ec2-instance

That’s a whole lot easier to manage and connect with. Don’t forget once you are connected that your terminal will almost certainly show a different prompt. You can exit your instance with

$ exit

This is only a very minimal of what is available to configure via the ~/.ssh/config file and you can read about the other options here.

Do you have tips or useful snippets you store in the ssh config file? If so please contact me via twitter or email.

Bullet Journalling With Notion

Photo: Wikipedia - Matt Raglan

Staying organised is something I have never felt at peace with. In an age of apps, methodologies and approaches I have never found one that I could stick at. I have tried to-do lists, Most Important Things, sandboxing time and all have failed. The only thing that came close was the Bullet Journal method.

The Bullet Journal method was created by Ryder Carroll for his own use. It has since developed a large following with physical notebooks and companion apps. The idea is best described in the video tutorial that Ryder created.

I have used the approach on and off for a couple of years. The big issue that I faced was capturing notes and idea’s when my notebook was not with me. Like most people, my brain doesn’t work an eight hour day. I tried some of the Android Bullet Journal apps and they were terrible. The official one is a companion app which aims to support the method when you are not with your journal. The other issue I faced was time. I was struggling each day to get the time to rewrite a list which at times was long, to a new page. This ate into any time I had for reflection and journaling.

What I really wanted was a good electronic version of Bullet Journal. This would make using it easier as I always have a laptop or phone within easy reach. As always how I want it may differ from how someone else wanted it so I needed the solution to be flexible.

And then I found Notion.

I have written a little about Notion before but it is now my go to tool for many use cases. Originally released in 2016, I only discovered it earlier in the year. It has now replaced Trello and Evernote amongst other apps I previously used. There are a couple of things Notion needs to improve. These including improving the start-up time and offline mode for the Android app. They also need Vim bindings but that’s something they are not keen on according to Twitter posts.

Anyway, I have created my own Bullet Journal using Notion. I have not created a template yet. I am still incrementally improving my approach even after a couple of months. I did look for an existing template and none of them fitted my needs or was over complicated. So this is how I have created my workflow:

  • I started with a top-level page called Bullet Journal. On that, I have two blocks at the top. In the left block, I have the months of the current year as linked pages and a toggle-list to move and hide previous years. On the right, I have my collections as a list. I also have a toggle-list in this section for archived collections. Below these sections, I have a calendar that acts as my forward planner and reminder tool. I did previously store reminders with tasks if needed but as you will see I duplicate pages as I move forward and so I ended up with notification hell. Instead, now I add an entry to the calendar and assign a reminder here. I also only set reminders on critical tasks. I consider everything else equal and handled in a kanban style manner.
  • Collections are just generally standard pages of bullet-pointed notes.

  • A month page contains two blocks at the top. On the left, I have links to each day page for the month. On the right, I have my monthly tasks and goals in toggle-lists. Below them I have my monthly log which I have created as a table. Three columns, Day, Date and Notes. No links or reminders. Just prefilled at the start of the month from my forward planner and maintained for reference. I start each day by duplicating the previous days page an relabelling it. I then spend some time setting my Most Important Tasks and arranging my lesser tasks so I know what I am working on that day.

  • The day page looks busy but is quite simple. At the top I have a block labelled Most Important Tasks. This is a checklist based list of no more than 3 tasks that I have to achieve that day not matter what. Then I have a Task board which is where I add my tasks. Four simple columns to track what I have to do, whats in progress, whats blocked and what I have completed. Below that I have two blocks. On the left, I keep notes and on the right I track events. Below these is a final block labelled Daily Summary which I keep a journal of what I have worked on and personal facts, feelings and memories. This acts as both a work jounral and a personal one.

That’s it! The process of creating the pages made me think about what is important for me to capture and track. This is the most organised I have felt in a long while and I am finding that I am capturing more thoughts and achieving at least my Most Important Tasks if not more from my task list each day.

How do you stay organised? If you have thoughts or suggestions around this subject please contact me via twitter or email.

Using NVM To Manage Node Versions Across Projects

Photo: Unsplash - Brennan Angel

A lot of the projects I am picking up as part of my work recently has been around Node and JavaScript. This ecosystem is one that I have studied from the sidelines. While I have used JavaScript for well over 15 years, it has always been in the browser. So some of the future posts here over the next few weeks will be useful snippets and brain dumps of stuff I am learning.

One thing that most developers agree on is the speed at which the JavaScript community moves. The rate at which package versions are upgraded and at which frameworks change can cause problems for one project. If you are managing more than one project then you need a way to manage multiple versions of Node. The answer is to install NVM - Node Version Manager.

How you install NVM depends on your platform. The Github page has detailed instructions that I will not repeat here. Once installed you will need to source the NVM file from your shell rc file (.bashrc, .zshrc etc):

source /usr/share/nvm/

(Note - The installation path may vary on your machine).

(nvm is not natively supported on Windows but there is an NVM-Windows package.)

Using nvm is really easy:

To install a new Node version for the local user you can execute nvm install version:

nvm install 12.13.0
nvm install 11.10.1

To switch between Node versions then you execute nvm use version:

nvm use 12.13.0
nvm use 11.0.1

It really is that simple.

If you want to force a given version for a project then you can create a .nvm file in the root directory of the project. In the file, you just add the Node version number the project should use wrapped in single quotes. Then when you switch to the project you can just run:

nvm use

The project Node version will be used.

If you want to use nvm to see what versions of Node are available then you can use:

nvm ls-remote

Nvm also has some aliases which target the latest versions of both the stable and unstable:


So running the following will install the latest version of Node:

nvm use node

You can, of course, uninstall versions using:

nvm uninstall 11.0.1

If you want to check the version of node you are running you can use

nvm current.

Nvm is a really useful tool to manage Node versions. I hope to see more people using it to set Node version information at a project level. This will speed up the process of getting a project running locally.

If you have thoughts around this subject please contact me via twitter or email.

Running Linux On A Thinkpad P52

Photo: Lenovo

A new job is as good as an excuse as you get to treat yourself to a new laptop. For over 12 years I have used custom-built laptops from PC Specialist as they provide great specs. Their costs are hard to beat and when on startup budgets they give the best bang for your buck. But, I have forever been a Thinkpad fan. I have owned a few over the years for side projects and personal use. I currently own a T430 which apart from a battery upgrade is still in everyday use. I was planning on switching full time to Linux, as I no longer needed Windows, so I decided to invest in a new Thinkpad.

I opted for a P52 on which I have installed Manjaro i3. The machine is a 6 core i7 with 16gb and a 512gb SSD. The screen is a 15 inch full HD affair which is powered by a combined Intel graphics card and an Nvidia Quadro P1000.

There is a raft of reviews about the P52 online about installing Linux. The Arch wiki as a great entry as a starting point and seemed like it was a good fit.

Before you begin you have to ensure that your BIOS is updated. Many articles from about a year ago mention bricked machines. You also need to ensure that your BIOS setting for graphics is set to hybrid. Follow the instructions in the Arch wiki article. I then installed Manjaro i3 community edition. I reformatted the whole drive and installed the non-free drivers. I then rebooted and everything worked except the trackpad and the TrackPoint. So I installed the Synaptics package and rebooted and I had a working machine.

sudo pacman -S xf86-input-synaptics

The next thing was to figure out the graphics situation. Manjaro had installed the Bumblebee driver. This provides Optimus two-card switching to provide the best battery performance. It does this by the Intel card being used most of the time offloading high resolution and 3D responsibilities to the NVidia card. There is just one problem and that is the external monitor ports are all hardwired to, you guessed it, the Nvidia card. At present, there appears to be no easy way around easily switching between cards. Bumblebee did not want to output anything via the Nvidia card no matter what I tried. It was time to install an Nvidia driver. So I opened the Manjaro Settings Manager and selected the Hardware Configuration option. I scrolled down to the Nvidia drivers that are available to install and right mouse clicked the one I needed and selected “Install”. After a lengthy process, I rebooted and then hit the command line to try out switching manually via Optimus-manager.

optimus-manager --switch nvidia    # Use Nvidia graphics

optimus-manager --switch intel    # Use Intel graphics

optimus-manager --switch auto    # Use other graphics

This works but anytime you switch you will be ejected from your graphical session. This means you get to sign back in again! Not ideal. Nvidia needs to update their drivers for Linux to solve this. I created some aliases for these commands:

alias switch-nvidia="optimus-manager --switch nvidia    # Use Nvidia graphics"
alias switch-intel="optimus-manager --switch intel    # Use Intel graphics"
alias switch-auto="optimus-manager --switch auto    # Use other graphics"

You need to watch out for is the power consumption and heat generation on running the Nvidia card only. There is a guide .

That left the only thing known not to work as the fingerprint reader. This is a shame but not a deal-breaker for me.

On the whole, this is a great laptop for the price paid. It is well built and has a great screen and keyboard. It feels like it will last forever without being heavy or bulky. Manjaro boots in seconds and was pain-free to set up and get a good working environment. I recommend the P52.

If you have any questions or suggestions related to the P52 please contact me via twitter or email.