Void

Conventions

Most programming languages have conventions. These could be for naming or code patterns.

rule-1752415_640

How does this help?

A simplistic view is that it helps to keep code consistent, especially when multiple people work on it.

A deeper way to look at this I believe is in reducing the cognitive load.

In cognitive psychology, cognitive load refers to the effort being used in the working memory.

If you have conventions, it is one less thing to think about. You do not have to spend mental capacity on thinking whether to name variables small case, capital case, camel case, with hyphen, underscore etc. You blindly rely on the convention. Same applies to code patterns. You look at the pattern and automatically grok the idea; without expending grey cells.

I strongly believe that all tech teams should have conventions wherever possible; outside code too. Freeing up any amount of working memory for things that matter will go a long way towards increasing productivity.

 

Advertisements

Anti features

When evaluating new technology, framework or library; a lot of importance is given to the salient features. While it is very important to know the positives, the negatives usually tend to be glossed over. Being aware of the shortcomings of a framework gives one the ability to anticipate problems down the road.

feedback-3239454_640

For example, let us take NoSQL databases. A lot of time is spent on singing paeans to the scalability, malleability etc of NoSQL databases while hardly thinking about the negatives that come with it.

Two simple techniques which give a good visibility on anti-features:
1. The very obvious one, Google for the shortcomings. Someone would have written a blog post on the interwebs highlighting how a framework or technology let them down. For example, take this post by Uber on how Postgres did not work as expected for them.
2. Comb through Github and/or JIRA peeking at the bugs raised and enhancements requested.

Both of the above will provide a good picture of the shortcomings. If you are evaluating a closed source proprietary technology, the above may not make the cut.

Once a mental note is made of the negatives, ponder on the scenarios where this might affect your usage. It helps to spend quality time on this as this will save one from a lot of future trouble.

If you think about this, this might sound very obvious but tends to be highly neglected. We get so caught up in the positives of something that the negatives tend to be ignored and this usually comes biting us back later.

Luck

I read an interesting article by Richard Wiseman on luck, which I would highly encourage everyone to read. The gist of the article is that people make their own luck and being lucky is something that can be learned.

An excerpt from the article:

Lucky people generate their own good fortune via four basic principles. They are skilled at creating and noticing chance opportunities, make lucky decisions by listening to their intuition, create self-fulfilling prophesies via positive expectations, and adopt a resilient attitude that transforms bad luck into good.

horseshoe-504821_640

Patrick O’Shaughnessy, in his podcast “Invest like the best“, talks to interesting people. He mainly concentrates on investors who have made it big, but once in a while he also chats with people from other walks of life. A common theme that keeps repeating in his interviews is how these people jumped at opportunities which others had shunned, their optimism and an attitude that stresses on continuous learning and development. These qualities eerily match with what Richard Wiseman says makes one lucky.

In the recent Farnam Street podcast, behavioral economist Dan Ariely says the following – “I gamble with my time. I take risks, I do things that do not seem like the right things to do”.

Two of the most successful and rich people of our times, Bill Gates and Warren Buffett are gung-ho about the future. Bill Gates actively champions positive thinking and wants all of us to cultivate this.

Probably luck is not luck after all. I am sure it is more nuanced than this, but something to ponder about.

Taking calls

Making decisions is part and parcel of being a leader. It might feel empowering to take calls but the hallmark of true leadership is in enabling others to do this. The smoother the decisions making process and lesser the blockers, the better it is for the organization.

question-mark-1872665_640

One route to get there is to create frameworks, rules, and principles for decision making. When your team wants to do something and are confused as to how to get there, they just clawback to the principles and use them. For example, take hiring. Having a clear-cut framework for hiring that covers all aspects starting from what questions to ask, how many rounds of interview, how to reject or accept candidates, what qualities to look for in candidates aids the hiring decision process. By having this, teams are allowed to make hiring decisions on their own.

Also, when taking calls, openly articulate your thought process. Make it clear as to what assumptions you did, what questions you asked, what data you looked at, what trade-offs you did. Laying out in the open the way you arrived at a decision helps others to traverse the same path on their own the next time.

To summarise, instead of just taking calls on behalf of others, go that extra mile to create a framework which enables them to do this independently the next time. Also, laying out the decision-making process in the open gives everybody an opportunity to peek at your thought process so that they can borrow it the next time.

Testing legacy applications

When contemplating on introducing automated testing in legacy applications, it is easy to get bogged down in terminology; unit testing, integration testing, regression testing, black box testing, white box testing, stress testing, etc. Quite a bit of time is spent in debates on unit testing versus integration testing, I have written about this before too.

A practical way to approach testing legacy applications is to first scope out the intention behind the test. Is it to test the behavior of a particular method, an API response or how an application behaves post an HTTP form submit? Next step is to jot down what and all has to be done to enable this. For example, if a database is involved, it can be mocked or a test database with bootstrapped data can be used.

software-762486_640

The gamut of changes needed to inject testability into an application that has never seen testing before should never be underestimated. The way you would structure testable code is vividly different from coding being incognizant of testing.

Take a look at the code below, how would you unit test getUser method without creating a database connection?

public class Foo {
    DbConnection connection = null;
    public Foo() {
        connection = <establish db connection>;
    }

    public User getUser(int id) {
        ////Query db and get user data        
        User user = new User();
        //Fill user with data from db
        return user;
    }
}

To mould this into testable code, DbConnection creation needs to be decoupled from object creation, like below:

public class Foo {
    DbConnection dbConnection = null;
    public Foo(DbConnection dbConnection) {
        this.dbConnection = dbConnection;
    }

    public User getUser(int id) {
        //Query db and get user data
        User user = new User();
        //Fill user with data from db
        return user;
    }
}

Since the DbConnection is independent of object creation, DbConnection can be mocked to unit test any method in the class. An application written without testing in mind would be replete with code like the above. Code patterns like these are one of the biggest hurdles in testing legacy applications.

Next step is to eliminate the resistance to testing. This would mean all the infrastructure and libraries needed to carry out testing are set up and a reference is readily available to follow. Bunch test cases into categories like unit tests, tests that need a mocked object, tests that need a mocked database, tests that need a database seeded with data, tests that need a web server etc. Post this, implement one test case for each of these categories. This will serve a dual purpose, the setup would be ready for each category and a reference readily available to others to emulate.

One aspect that is usually neglected is the effect of testing on the product release cycle. As a result of testing, more code, dependencies, and infrastructure is introduced which needs to be maintained. Along with working on new features, writing tests for these also has to be taken into account. While refactoring, it is not just the code that has to be refactored, even the test cases have to be refactored. This is a tradeoff between time to market, and maintainability and reliability.

Testing is no longer a chore it used to be, testing tools and frameworks have grown by leaps and bounds. With the advent of docker, headless browsers, Selenium etc; testing is very much within reach of most of the teams provided the intention is there and effort is put in.

Build versus buy

Consciously or unconsciously, as software engineers, we perennially take build versus buy decisions. It might be as trivial as copy pasting code from somewhere versus racking up our brains to write our own; using an already available library or writing one from scratch; using a time tested framework against designing one; building a piece of software internally as compared to buying one.

backdrop-21534_640

The way we account for the build versus buy decision varies. Some of the frivolous reasons for building in-house are NIH syndrome, hubris, and planning fallacy.  We generally tend to overemphasize our expertise, knowledge, and capability which naturally lead to building internally. Also, we underestimate the amount of work involved in creating software, only once we get our feet wet does the reality set in. A very valid reason for building internally is cost but when accounting for cost, we usually overlook the hidden cost of building software. Buying a software has an upfront monetary cost whereas by building internally we pay in the form of opportunity cost, talent cost, feature cost etc.

Build versus buy arguments are reminiscent of qualitative speak like “This is not our core expertise, we should be concentrating on solving our business problems”, “This is going to cost us a bomb, let us build in-house”, “We should have had this yesterday, building in-house will cost us another 6 months”, “Will that external product be able to handle our scale”, “Can we trust them with our data” etc. In most cases, build versus buy decisions are qualitative, it is not an easy exercise to quantify them.

When evaluating a product that is already out in the market versus building something similar, a cardinal mistake people commit is mapping features one to one. Even though having 100 different features looks rosy and attractive, usually we end up using only a select few. Instead of trying to match an external product feature to feature, scope out the features that you need or would probably use and then estimate the effort. Another is refinement. An external product will be refined and polished, but you may not need the same level of refinement. For example, you might not need a web interface for the product, a terminal interface would work fine for your use case.

When faced with the build versus buy decision, asking the following help:

  1. Is this my core expertise or is it something I can let others do for me?
  2. What is the cost of getting this done externally versus hiring people to build this?
  3. How much control do I need over this i.e can I live with some error, downtime or opaqueness?
  4. Will I really do a better job building this internally?
  5. Do I have the expertise needed to build this?
  6. Once I build this, will I be able to maintain and enhance?
  7. What is the opportunity cost of having this sometime in the future versus having it now?

Use the answers to the above as a beacon for the build versus buy decision.

Context

Sapiens, the book, gives an amazing perspective of the context in which today’s religions, society, social practises etc evolved and how in the current context, a lot of these are irrelevant. One of the core ideas presented in the book is that humanity, during the course of evolution, favoured social stability over individual liberty because trust was necessary for human advancement and the basis of this trust was a common belief in the same God, social practises, etc. Today, science and technology as well as robust social institutions and concepts like democracy, liberalism, capitalism etc form the basis of trust. In short, the context does not hold true today but we still continue with the practises. We can draw parallel with this to the way organisations blindly adopt technology, frameworks and processes from other places without understanding the context around which these evolved.

question-mark

During the course of my professional life, I have heard a lot along these lines; Netflix does micro services, let us also do that; Google and Facebook subject interview candidates to intensive data structure and algorithm questions, let us practise the same. Adopting something without understanding the context is a recipe for disaster. As a thought experiment, let us take micro services. Micro services evolved in tech organisations with complex products handled by multiple independent teams craving for control and autonomy without stepping on each others toes. Also, for micro services to succeed, you need to put in a lot of effort into alerting, monitoring, orchestration, devops etc. Without these, micro services is a bomb waiting to explode.

When borrowing technology or processes from other places, a lot of effort needs to be put into first understanding the context around which these evolved in the said place and also what is needed to make these work. Blind adoption usually leads to unmitigated disaster.

Look ma, no schema

Due to the plethora of NoSQL databases available, schema-less is a tantalising option these days. While starting on a new project, NoSQL databases look attractive but reality sets in when the maintenance problems start creeping up later.

nosqlpng

 

If you are doing anything with data, you need to know the schema of that data. What this boils down to is whether this schema is explicit or implicit. In relational databases, the schema is explicit and well documented whereas in NoSQL databases, the schema is implicit i.e it is maintained in code. All the goodies that you get with relational databases like integrity checks, constraints etc should be taken care of in code.

Products go through a multitude of changes, features get added and axed and in order to accommodate this, the schema has to change accordingly. In relational databases, carrying out schema changes on tables with humungous data is a daunting problem which requires considerable planning and effort. This problem is not present in NoSQL databases, but again, you end up managing this in code. In order to handle multiple versions of the schema, code gets littered with if else statements. This gets even more messy as this is spread across the code base in multiple places wherever data is being handled. In relational databases, you handle schema changes once and for all, in NoSQL databases, you continue to do it in code long after the change.

Multiple people work on code at different points in time, people join and leave teams but code lives on. This is when the maintenance problem starts raising its ugly head.

A big reason a lot of startups opt for NoSQL databases is due to the constant flux in these organisations. Requirements change frequently due to which a stable schema design becomes next to impossible. In this landscape, NoSQL databases look like God’s gift to mankind. If your company does not fall in this bucket and you find yourself tempted to use a NoSQL database, take a good hard look at the problem and ensure that it is worthy of a NoSQL database. There are problems which are better solved with a NoSQL database but these are far and few.

10 things you did not know about Vietnam

Sorry, could not help with the snarky title. We recently took a vacation to Vietnam and this is a collection of unconnected thoughts and observations about the country and our journey.

poster-nva-1970-poster-usa-hueys

During our travel, we visited Ho Chi Minh City, Da Nang, Hoi An, Hue, Hanoi and Halong Bay. In all these places, infrastructure was amazing, almost on par with western countries. In Hanoi and Ho Chi Minh city, there are abundant parks and public spaces. They are very well maintained too.

There are walking streets everywhere. Most of these are regular streets which get converted to pedestrian only movement during the night. You will spot umpteen eating and drinking options in these streets. These walking streets are not as scandalous as the ones in Thailand.

Food is a big part of the culture, street food is abundant. It is a paradise for non vegetarians, not so much if you are a vegetarian. Noodle soup(Pho) and banh mi are two of the most popular delicacies. Banh mi means bread in Vietnamese, usually it is sold stuffed with veggies and/or meat.  Banh mi is a relic of the French past like our Pav(Vada Pav). There is a version of noodle soup called hot pot which is cooked right on your table which is delicious. People watching seems to be a big thing, lots of cafes lined with chairs facing the street. I am in love with Vietnamese coffee, it is black coffee with condensed milk, tastes amazing.

Vietnamese seem to have a thing for “The North Face”. Fake North Face products abundant on the streets. Giving them company are Nike, Superdry and Under Armour. Adidas, Reebok and Puma are conspicuously absent.

Traffic is chaotic. Two wheelers zipping past everywhere breaking all rules. You can rent two wheelers in all the cities, which we did. There is neither license check nor passport deposit, it is a honour based system. Toyota is everywhere. We checked with a taxi driver as to why Toyota seems to be omnipresent. Since there are so many two wheelers, scratches and skirmishes are common it seems. Hence Vietnamese prefer Toyota which is easy to maintain and spare parts are economically priced.

Communication is a challenge. Google translate was a life saver. It was much easier to just type in translate and show to people.

Vietnam is blessed with abundant water, water bodies everywhere, in cities as well as countryside. From the 60th floor of Lotte tower in Hanoi, we could spot innumerable lakes.

Museums and historical places scream jingoism. Glorification of Vietnamese struggle against the French and Americans seem a bit in your face.

Vietnam seems to be on the path to becoming an economic powerhouse. Signs are everywhere, from the burgeoning constructions to commercial towers competing for the most number of floors title.

Vietnamese are a friendly lot, they try their best to make things happen for you. We have hardly had bad experiences with people apart from a parking attendant in Hanoi who lost his cool due to the language barrier.

All hotels including our room in the cruise had slippers as part of standard accessories which was new. Also, in some of the public toilets, you had to change your footwear to slippers present there, a nice hack to keep the toilets clean.

Indian cinema and tv shows seem to be very popular. Our van driver was glued to Telugu movie scenes on his phone and a taxi driver told us he is a big fan of Hindi movies.

Internal air transport is economical, couple of low cost carrier options.

Souvenirs and trinkets are sold everywhere. Propaganda posters are really cool. Vietnamese seem to have a soft corner for Tintin, various posters and fridge magnets of “Tintin in Vietnam” or “Tintin in Saigon”.

Vietnamese script is English with accents. A French person created the script for Vietnamese. Original Vietnamese script is long lost it seems.

Vietnamese seem to love kids, we had three toddlers in our group, they were greeted with chocolates and souvenirs by strangers almost everywhere.

From a cultural perspective, Vietnam and India share a lot in common. Vietnam has a rich cultural past, dating back centuries. In fact, at one point of time, Hinduism was the dominant religion in Vietnam.

While coming back, we took Malindo air. Malindo air was a pleasant surprise, friendly stewards, ample leg room and in flight meals.

When we told people that we are going to Vietnam, all asked us why and we did not have an answer. It was well worth it though.

Shoe Dog

nike

Phil Knight, founder of Nike, pens down the early days of Nike in this part memoir, part biography, part business book; “Shoe Dog”. The book starts with Phil Knight’s idea to sell Japanese made sneakers in his home country USA, his business school thesis supporting the same, his journey to Japan to ink the deal and the subsequent travel around the world post which he dedicates his life to building Nike and the struggles thereafter.

In today’s interconnected world where communication is instant and automation is the norm, reading about running a business when these were non-existent is fascinating. Nike during it’s founding days was closer to today’s new age startup than to any old school business as the company prioritized growth over security and cash in the bank. His anecdotes regarding the dearth of capital, constant tussle with the bank on rapid expansion, his bank asking him to scale down his ambition and focus on capital accumulation; give insights on the business mentality of the yesteryears.

Throughout the book, Phil Knight talks about his hands off management style. He styles his management on the below quote from Antoine de Saint-Exupery.

If you want to build a ship, don’t drum up the men to gather wood, divide the work and give orders. Instead, teach them to yearn for the vast and endless sea.

Profile of the Nike founding team is far-fetched from the general imagery of traditional old-school businessmen. They seem to be misfits who found a home at Nike, at least Phil Knight thinks so. No wonder the whole company rallied around doing iconoclastic things that many businesses would not even think of during those days.

All in all, the book is a great read. I was hoping to read more about Nike’s marketing strategy and how it evolved, but there is hardly any mention of this. Probably for another book I guess.

Reading Shoe Dog brought back fond memories of reading “Made in Japan” years back.