Developers path to seniority

What seniority means for a software engineer? Is it familiarity with frameworks, libraries or something different? In this post, I will try to summarise my perspective on how it is changing for me. Got a lot of view during the last three years when I have lead or participated in a decent amount of interviews for engineering roles, including the C-level executives. Let state the obvious: fair and good hiring is super hard. During the hiring process, you try to assess the seniority of the candidate(and other qualities for sure) according to the company career ladder. As a reference, industry-respected and well-known ladder description can be used Google career ladder. If you haven’t had an opportunity to familiarise yourself with it, take the time and do so, it is definitely worth understanding. Google career ladder construction anchored in Google perfect team study. This post doesn’t attempt to mimic Google research but rather provide a starting point and raise curiosity. Excellent management is where the resulted outcome of the team is far greater than the pure sum of individual contributions. 

Seniority levels are usually a combination of technical “hard” skills and other skills collectively referred to as “soft” skills. Unfortunately, relatively few companies go beyond this level of explanation. 

Junior level is characterised by a strong desire to learn new tools, frameworks and techniques. Often connected with black and white view on problems and when solving a task, junior developers can come up with a single possible solution or more with slight modifications. It is nothing wrong to be at that stage, and healthy teams often contain some junior developers as they bring fresh trends and passion to the teams. However, having more than 25% of junior developers in the team is challenging as they require more attention and slows the team down or affect the quality. Be careful with this mix.

Gaining seniority than then goes on a few axes – technical skills, context developer is using during the evaluation of possible solutions and ability to communicate effectively. Junior developer has limited technical skills, and his context is limited to code he is writing and communicates solely in terms of code, requirements or tickets. Context is a vital vehicle for guiding a developer in two remaining axes. As technical skills are growing number of the possible solution raises as well. Context can be divided but not limited to the following scopes:

Codebase – Limits the knowledge to the current codebase, used technologies and design principles and thinking in those low-level terms. This definition can be confusing as project codebase is involved every time as the ultimate source of truth but what differs is the level of abstraction. Developers are growing by operating bigger codebase and experience on different project codebase.

Development habits and practices – This area covers topics like where to apply which kind of tests. Where are the areas you can compromise if chasing time, and what are the real costs? Tech debt management. Essential features for long term supportability. Those items can be categorised under some risk management and damage control practices.

System design – Designing a system for performance, scalability, security and similar system-wide aspects. Defining thread zones and expected failure scenarios. Think in terms of consistency and ability to enforce those policies on the platform level. What can be handled on infrastructure level vs what is necessary to address in the application code?

Different mindset/roles – Understanding of other functions and associated mindsets of people participating in the development process (system engineers, quality assurance, machine learning engineers, project managers, etc.). What helps the best in this area is to try out the majority of those roles. Getting the role mindset will simplify communication during cross-team communication.

Software development life cycle – Ability to foresee and expect requirements which might not be implicitly obvious or stated in the desired functionality description. Understanding of product lifecycle stages starting from ideation till end-of-life. An item like supportability, troubleshooting etc. What helps in those aspects is to take the perspective of technical support personnel and think in terms of what-if. How difficult would it be to discover that component/feature X doesn’t work as expected.

Technology overview – Knowledge of technologies and alternatives gives you lego blocks for building a final solution architecture. This is especially important for the cloud-based product as you are trading a cost for a speed of delivery. Similarly, the same applies to programming languages. Those have specific features, design patterns etc. 

Cross disciplines – This context is pretty similar to `Different mindset roles` with an only difference; it is focused on actual skills necessary in those roles and effects the tools have on team dynamics. Disciplines like development, operation, infrastructure, marketing and similar. 

Cross-level and cross-department awareness – Understanding main objectives, areas of competence and levels of abstractions those people operate on. Unfortunately, even though role titles repeat competencies and responsibilities differs significantly between companies. That is what makes the execution different for each company and is one of the secret sauce of success. Effects are visible in accounting and balance sheets. 

Management and leadership skills – Guide the team without command and control approach. Leading the change throughout the team, getting the buy in to support the change and move things forward.

Business domain – Understanding of industry you operate in helps you to drive better value for your customers by combining your technical abilities with domain knowledge.

Business models – Understanding how the business makes money on the product you build helps you to understand key aspects of the technical solution in terms of desired points of flexibility, scalability and cost management.

Knowledge and experiences in those scopes provide a better context for making decisions in the bigger picture and finding a more strategic solution for given conditions. Helps you to drive communication more effectively as you can think more like your counter-party and understand his point of view. Lastly, you should be able to come up with a plan of delivery iterations with a value-added in each iteration and mitigated risk. 

The more senior you get on technical skills and proceed on the career ladder, the more the role start rely on your leadership skills. The vast amount of companies than forces people to manager roles but some (including Google, Facebook, etc.) allows to continue on technical track and label those positions as Principal or Staff Engineers. The role of those engineers is usually to improve the engineering culture and best practices of the teams apart from solving complex engineering tasks. 

I neglected at least one aspect in my writing, the effect of personal characteristics and perspectives for particular roles. I am not going into those but instead refer to great Neil blog with people topologies

What is your perspective on the “developer’s” seniority? Let me know in the comment section below, or you can reach me on Twitter.

Resources I found the best on those topics except those already mentioned in the text:

Building Secure and Reliable Systems: Best Practices for Designing, Implementing, and Maintaining Systems

Accelerate: The Science of Lean Software and DevOps: Building and Scaling High Performing Technology Organizations

Team Topologies: Organizing Business and Technology Teams for Fast Flow

The Five Dysfunctions of a Team

Managing Humans

The Invincible Company

Value Proposition Design: How to Create Products and Services Customers Want

The Business Model Navigator

Scaling Terraform(IaC) across the team

HashiCorp Terraform is a popular tool for managing your cloud infrastructure as code (IaC) in a cloud-agnostic way (same tool for various cloud platforms). Instead of unifying all capabilities for different cloud platforms, the core concepts exposed to the end-user via Terraform provider concept. Terraform offers providers for all major cloud vendors and other cloud services and technologies as well, e.g. Kubernetes.  

This blog post doesn’t aim to be an introduction into Terraform concepts (official documentation is quite ok) but instead sharing an experience with using a Terraform in a distributed team, tools that come handy and all things that make life easier. Even though HashiCorp offers Terraform Enterprise this option is used quite rarely at least on “small/er” projects so we won’t be discussing this option here. I openly admit that I have zero experience with this service so I cannot objectively compare. I will solely focus on using the open-sourced part of the project and Terraform version 0.12.x and higher. 

Terraform maintains the sate of the infrastructure that manages in the state file. Format of Terraform state file is version dependant without strict rules on version compatibility (at least I wasn’t able to find one that was reliably followed and guaranteed). Managing state file poses two main challenges:
1) manage/share state across the team
2) control/align the version used across the team

The first aspect, different teams solve differently. Some commit state file alongside the configuration to version control system which is far from ideal as there might be multiple copies of such resource across the team and requires some team coordination. On top of that, state file contains sensitive information which is impossible to mask and such doesn’t belong to the source control system. A lot better approach is using Terraform remote backend, which allows true concurrent approach. Capabilities depend on the concrete implementation used. The backend can be changed from local to remote easily as is migrated automatically. The only limitation is that merging and splitting state file is allowed only for the locally managed state. 

Managing Terraform version management is centred around providing frictionless version upgrades for different Terraform configurations that align across the team with assuring that state file won’t get upgraded accidentally. To make sure that your state file won’t get upgraded accidentally put version restriction to every configuration managed e.g.

terraform {
  required_version = "0.12.20"
}

To align the team on a uniform Terraform version for every single configuration managed use tool for Terraform version management, e.g. tfenv. Put the desired version of to .terraform-version file located in the folder together with configuration. Tfenv automatically switches to appropriate version as needed, when new version encountered you need to run tfenv install to download a new version. If you want to check version available:

$ tfenv list
* 0.12.20 (set by /Users/jakub/test/terraform/.terraform-version)
  0.12.19
  0.12.18

As the number of resources or organisation grows so does the state file. Which leads to increased time for configuration synchronisation and competing for a lock on a remote state file. To increase the throughput and allow team DevOps mode(clear ownership of the solution from end to end), you might want to divide the infrastructure and associated state files into smaller chunks with clear boundaries. To keep your configuration DRY hierarchical configuration tools like Terragrunt comes to rescue and reduce repetition. 

A growing number of users poses challenges as well as benefits which are the same as on application code written in, e.g. java or any other programming language. What is the real motivation for Infrastructure as a Code (IaC). How to setup standards and best practices on the project? Terraform offers a bunch of tools embedded. To make sure that code is properly formatted according to standards use fmt utility, which is pluggable to your CI/CD pipeline or pre-commit hooks.

terraform fmt --recursive --check --diff

For your re-usable Terraform modules it is good to make sure they are valid though it doesn’t catch all the bugs as it doesn’t checks against cloud APIs, so it doesn’t replace integration tests.

terraform validate

Getting an idea what will change, diff of your current infrastructure against proposed changes can be easily achieved via the generated plan

terraform plan

Enforcing security and standards are a lot easier on IaC as you can use tools like tflint or checkov which allows writing custom policies. We conclude the tool section with awesome Terraform tools which provide a great source if you are looking for something specific.

In this blog post, we just scratched the surface of Terraform tooling and completely skipped design and testing, which are topics for separate posts. What are your favourite tools? What did you find really handy? Leave a comment, share your tips or you can ask me on twitter.

Communication in distributed teams using Slack

Some time ago I wrote a post about tools I found useful when working in a distributed team. Working habits are changing and companies which grasp it will benefit from access to the broader talent pool and possible benefits when managed rightly. However, managing remote teams pose significant challenges. This post isn’t going to discuss how to structure teams or how to address araising challenges but rather focusing on things I found useful when working in a remote distributed team.

In the past years, Slack become defacto standard in this area even though I keep hearing from various teams that it didn’t meet quite their needs. If you have experience with the different tool I will be happy if you can share your experience in the comment section below the post.

Following section lists features I discovered really useful during working in a remote distributed development team.

  1. Snooze notifications –  to protect your focus time and boost your productivity. Break day to focus units where all distraction is disabled.
  2. Highlight words – can save your time to skim through unread messages available via Slack > Preferences > Notifications > My Keywordsslack highlight keywords feature
  3. Reminder tools – on each message you can set a reminderslack remind me about this feature
  4. To quickly start google hangout meeting – use command /hangout and the call will be initiated
  5. If you want to append ¯\_(ツ)_/¯ to channel – type /shrug command
  6. Use advanced slack search – start in search box with plus signslack advanced search
  7. Create Poll – use the command: /poll “Question?” “Option1” “Option2” “Option3” …slack simple poll
  8. Convert direct communication to a private channel. To direct communication must be included more than one party involved and the resulted channel is always private with no option to make it public. You can, later on, invite new participants with the option to see the channel history.slack direct message to private channel
  9. Channels for dedicated groups or around topics of interest are standard but what I found really useful is User groups feature which allows communicating with a group of people across the channels.
  10. Use stars to create an instant to-do list. You can mark any message or phrase with a star next to the time-stamp. It’s almost the same as bookmarking. Hint: if you mark messages with the task then you’ll get a personal to-do list which is really convenient to form during the conversation.

This concludes my top 10 slack features I found really useful while working in a remote distributed team. If you have other tips and tricks please let me know. Also if you found other useful tools please also share that experience in the comment section below.

Online collaboration tools for distributed teams

During past several years, working habits and working style has been rapidly changing. And this trend will continue for sure, just visit Google trends and search for “Digital nomad” or “Remote work”. However some profession undergoes this change with a better ease than others. But it is clear that companies that understand that trend benefit from that.

Working in a different style requires a brand new set of tools and approaches which provides you similar working conditions as when people are co-located at the same office. Video conferencing and phone or skype is just the beginning and doesn’t cover all aspects.

In the following paragraphs, I am going to summarize tools I found useful while working as software developer remotely in a fully distributed team. Those tools are either free or offer some free functionality and I still consider them very useful in various situations. The spectrum of the tools starts with some project management or planning tools to communicate.

For the communication – chat and calls Slack becomes standard tool widely adopted now. It allows you to freely organize your teams, let them create channels they need. It supports a wide range of plugins e.g. chatbots and it is well integrated with others tools. Provides application on all desktop and mobile platforms.

slack

When solving some issue or just want to present something to the audience screen sharing becomes a very handy tool. Found Join.me pretty handy. Free plan with the limited size of the audience was just big enough. Working well on Mac OS and Windows, Linux platform I haven’t tried yet.

joinme

When it comes to the pure conferencing phone calls or chat Discord recently took my breath away by the awesome sound quality. Again it offers desktop and mobile clients. plus you can use just browser version if you do not wish to install anything on your PC.

discord

Now I slightly move to planning and designing tools during software development process and doesn’t matter if you use Scrum or Kanban. Those have their place there. Shared task board with post-it notes. The one I found useful and free is Scrumblr. The only disadvantage is that it is public. It allows you to design the number of sections, change the colours of the notes and add them markers etc.

scrumblr

When we touched an agile development methodology there is no planning and estimation without planning poker. I found useful BitPoints. Simple yet meeting all our needs and free online tool where you invite all participants to the game. It allows you to do a various setting like the type of deck etc.

bitpoints

When designing phase reached shared online diagramming tools we found really useful is Sketchboard. It offers a wide range of diagrams types and shapes. It offers traditional UML diagrams for sure. Free versions offer few private diagrams otherwise you go public with your design. Allows comments and team discussion.

sketchboard

Sometimes we just missed traditional whiteboard session and just brainstorm. So a web white board tool AWW meet our needs. Simple yet powerfull.

aww

This concludes the set of tools I found useful during a past year while working in a distributed team remotely. I hope that you found at least one useful or didn’t know it before. Do you have other tools you found useful or have better variants of those mentioned above? Please share it in the comment section!

Build Number

One of the most important thing during the SDLC (for sure apart from the other stuff) is to keep control over deployed artifacts to all environments at any given time. Lack of control leads to chaos and generates a lot of extra work to the team, degrades throughput, morale and motivation. No need to even mention that arguments among team members regarding deployed features or fixes definitely do not contribute well to the team spirit.
One of the common approaches mitigating this risk is generating a build number to every single build fully automatically. Let’s take a look at how to accomplish this in common project set up – maven project build on build server e.g. TeamCIty. Sample web application follows.
Common place where to store such kind of info is MANIFEST.MF file. All kind of archives have this file located in /META-INF/MANIFEST.MF. Various technologies like OSGi use this location for various metadata. Taking advantage of maven-war-plugin the content of MANIFEST.MF can be easily customized as follows (${xx} are maven variables):
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: ${user.name}
Build-Jdk: ${java.version}
Specification-Title: ${project.name}
Specification-Version: ${project.version}
Specification-Vendor: ${project.organization.name}
Implementation-Title: ${project.name}
Implementation-Version: ${project.version}
Implementation-Vendor-Id: ${project.groupId}
Implementation-Vendor: ${project.organization.name}

To set up a maven project pom file is pretty easy:

         
            
                org.apache.maven.plugins
                maven-war-plugin
                
                    
                        
                            true
                            true
                        
                        
                            ${build.number}
                        
                    
                
            
        

Where build.number variable gets supplied by build server in arbitrary format, e.g. for TeamCity build server:

Build number is visible in build queue status page as well:
To access these project build specific information simple jsp page can be created:
The controller accessing these information using Spring MVC (simplified example) can look like:
@Controller
 public class ProjectInfoController {

     @RequestMapping("/info")
     public ModelAndView getProjectInfo(HttpServletRequest request, HttpServletResponse response) throws IOException {

         ModelAndView modelAndView = new ModelAndView("projectInfoView");

         ServletContext servletContext = request.getSession().getServletContext();

         Properties properties = new Properties();
         InputStream is = servletContext.getResourceAsStream("/META-INF/MANIFEST.MF");

         properties.load(is);

         modelAndView.addObject("buildBy",properties.getProperty("Built-By"));
         modelAndView.addObject("buildJdk",properties.getProperty("Build-Jdk"));
         modelAndView.addObject("specificationVersion",properties.getProperty("Specification-Version"));
         modelAndView.addObject("specificationTitle",properties.getProperty("Specification-Title"));
         modelAndView.addObject("implementationVendor",properties.getProperty("Implementation-Vendor-Id"));
         modelAndView.addObject("buildNumber",properties.getProperty("Build-Number"));

         return modelAndView;
     }
 }

Accessing MANIFEST.MF in JAR file has a different approach. Motivation taken from Spring source code:

Package  package = someClass.getPackage( );
String version = package.getImplementationVersion();

JSP page or other presentation layer shouldn’t be a problem for anyone.