I regularly interact with a wide variety of candidates right from college graduates to very senior engineers, one story that I keep hearing is that every one prepares a lot for the interviews solving DSA problems. It is like rote learning, one has to keep practising a lot just for the interviews.

I have never understood the need to test the depths of programming for regular software development. Software development in most cases require skills that does not need deep understanding of data structures and algorithms. A fundamental knowledge of programming is enough. What is needed is communication skills, it is extremely hard to specify software requirements in writing just like how input and output are expressed in competitive programming.

Photo by Nemuel Sereti on Pexels.com

A programmer’s biggest challenge is to understand the value and intent behind a requirement, what impact it can create for the business and come up with a solution that is easy/quick to develop, maintain and extend. The main point here is, it should be fast/easy, cheap to develop/extend, should be maintainable and not be hard to fix when critical flaws like zero days surface. Communication, discipline on keeping up with clean code, grit to keep the code continuously tested, integrated and deployable are key skills. Product owners will need multiple iterations and increments to get to a desired state; faster and easier the communication then faster is the desired result.

A big myth in hiring space is that if programmers are good with DSA, then we can throw any problem and a deadline at them and we can achieve a lot. This mindset is the root cause of a lot of software rot, making it extremely hard to onboard new developers and keep existing developers productive. My observation has been that candidates tuned so well to crack DSA problems expect clear specifications often broken down to LLD and tasks with clear input and output. They find it very hard to collaborate with peers or train new developers. When they face ambiguity, they go haywire instead of resolving it; often end up treating it like competitive individual sport whereas software development is a complex creative process.

A lot of people quote about Henry Ford’s remark, “If I ask my customers what they wanted, they will say faster horses”. We do not know if he really said those words but it is true that many of the ideas will always be incremental and not inventive, be it technology or ways of working.

If you ask bosses what they wan’t, everyone unanimously says “Longer working hours” especially more vehemently in the software development industry. My observation has been that with lots of automations and tech abstractions, the time taken to develop software has come down by a few magnitudes, compared to what it was a decade ago. What needed large teams with extensive management overhead can be done with smaller teams with fewer oversight.

In mature domains like mechanical and civil, breakthroughs are very less frequent; hence templating the work into easy to do steps that are verifiable by non techies is very productive. An abstract requirement will be translated to actionable steps, broken down into units of work and assigned to people to complete. Once the task is complete, it is very easy to verify by anyone else and the end of construction phase is typically the end of the project. It makes things rigid and predictable, so it has a linear relationship between number of people, number of hours and dependencies.

Software development on the other hand is very difficult to convert from abstract to concrete, any infusion of rigidity risks not getting the intended outcome. The combination of ever improving tech landscape, difficulty in communicating what a working software should do, the nature of knowledge work which degrades when stressed, makes it very hard to have a proven relationship with working hours, number of lines of code and number of people.

Photo by Tara Winstead on Pexels.com

When dealing in a dynamic environment, there is more than one way of doing things, sometimes exponentially time saving ways can be found if we strive to make the design simple. One personal example I had was to write a program to convert roman numbers to decimal. I wanted to shake off the inertia and start writing code, I dived deep into the code thinking in terms of objects, writing a lot of tests and completed it after a few hours when I was convinced that the solution is complete and clean. The next day I realised that I was constrained by the need to keep going, that I never questioned if my solution could be simpler. I just spent 20-30 minutes to rewrite it in functional paradigm and got that done under 10 lines of code in one file which was 100+ lines across multiple files. For an outsider, thinking hard about the problem looks like inactivity, wasting time and not showing urgency; to me it came down to a super simple solution that is very easily be read and maintained by others.

Bosses are often tuned to look for urgency and activity as indicators of productivity. Also in the software service industry irrespective of the productivity, the number of hours billed directly impact profits; hence bosses love long working hours. In the software product industry though billing hours don’t matter a lot, the apparent busyness of people is expected. As a result, no major improvements happen as it is always business as usual sometimes even slowing down overall, creating physically and mentally unfit individuals over the long run.

On the other hand if teams are given freehand, then they also tend to extend the thinking phase into analysis paralysis. This can be broken down by mandating outcomes and impact on fixed timelines than output and effort. It is an art and takes a determined effort to build high performing teams that keep punching above their weight. The easy way out is demanding long working hours.

If you are engaging a knowledge worker on physical effort, then you are buying into mediocrity

Shift left was applied to testing and then the testing scope which was initially functional expanded to include performance, security and resilience. So far it is fine, the problem it brings is when the experience aspect is shifted to the extreme left. This ends up with product having endless loops of perfecting the wireframes and experience aspects to get a perfect shot at the finished product.

Imaging you are playing paintball, you have to shoot down very very fast erratically moving drones. You get two options, (1) a gun which can be reloaded as many times as you want and fire in quick succession but needs 2-3 hits to take down a drone, (2) a gun which can be reloaded only once in a few minutes and takes down a drone in 1 hit. If you are given 10 minutes and you win based on how many drones you take down which would you prefer. If you prefer second, then you have shifted everything to the left without the option to learn from your misfires.

Shift left should be for the delivery mechanism. Functionality, security, performance, resilience all should be tested and if at all they fail should fail very very early, closer to the time the code was committed. Along with this an experimental and dark release setup that can be used to learn user behaviour & adoption. This helps the product send umpteen changes to the end user and get the one that works to remain in production.

There is a lot of value in UX research, paper prototype, wireframes and illustrations but when shift left is applied to this, then each iteration and increment becomes very expensive and forces people to figure out as many variables as they want, which is not possible to discover until an end user uses the system.

Misfire is a given in product development, if we shift left everything we have less chances to learn from our misfires. We should also optimise to validate the hypothesis with a working software, so an idea should see reach the customer for validation as much as possible.