Should you learn Docker?

Maybe yes. Maybe no.

If you ever write server/back-end software, it should be a requirement today that you know Docker.

If you create applications, it’s good to know Docker so you can create a standardized build environment. You never really want your application release builds to come off a developer system, and it’s even better if the standard build system can be defined in software.

If you want to run a specific version of a database on your development system, then Docker can do that pretty trivially as well.

If you have problems with version conflicts between various installed environments (Python 2 vs 3, various gcc[lib] versions, other tools installed globally, etc.) then Docker can be useful to set up the perfect environment to run a picky tool, and once it’s working you can share that environment with a coworker and know that it will just work.

Docker is a tool. You should learn it if it will help you do your job. The above examples are not exhaustive. Any time that it would be good to have a standardized environment on your development system, for testing or sharing or running specific software, Docker would be useful.

But if you never need it for the above reasons or otherwise, then no, you don’t need to learn it. It wouldn’t hurt to learn it just in case. But there’s no “should”. It’s really, really not hard to learn, though. At least if you understand the command line.

Why do backend developers have more confidence in their profession than frontend developers?

Because 99% of the time when someone identifies as a front-end developer they are saying that they have not been a developer for very long.

Think of it this way. On the web, Ajax was “invented” in 2004 (actually Outlook was doing it in 1999 but shh…we can’t give Microsoft any credit). It did not become a central part of most web developers’ lives till 2008/2009 or so. Even then, Javascript was avoided by many until frameworks started coming out in the early 2010s.

So what were people who were already established developers pre-2010 doing? Working largely on the back-end. So now that they do a lot of front-end work too, they face the choice, do they brand themselves as a “front-end” or a “full-stack” developer? I certainly choose the latter.

Which leaves most people who embrace the “front-end” moniker as people who have been coding professionally for less than six years. So yeah…they’re less sure of themselves.

For the record, I use the “front-end” and “back-end” terms above in the manner I see them used more often, with “back-end” meaning server-based languages, databases, etc; and “front-end” meaning HTML, CSS, and Javascript. Personally, I dislike those definitions and prefer “back-end developer” to indicate how good someone is at understanding architecture, performance, databases, and security; and “front-end developer” to indicate to what degree someone thinks about human-computer interaction, responsiveness, UI optimization and reusability, browsers, responsiveness, and accessibility. When you formulate definitions this way you start seeing these as two largely orthogonal dimensions of a square, rather than anything mutually exclusive.

Disclaimer: I use 99% rhetorically. It certainly is an overwhelming majority but I haven’t done any data gathering on the subject. That being said, I certainly don’t claim that front-end development is easy. There’s a huge amount of churn. There aren’t many other areas of development where people have to actually stay on top of language specs. 

Why React Dev’s Like to Hate Vue.js

After having worked on React development on medium/large scale apps, I have to admit that VueJS is like a breath of fresh air.

In my opinion, most developers are having as I call it the “Simplicity (Un)reasoning” bias, which means: if it is simple to learn, simple to use then it is for simple projects. Crazy right?

Meanwhile, the arguments in favor of React or Angular 2+ are dubious as well.

Angular is for large teams because it enforces you to write code in a typed way because of TypeScript. Yes but React and Vue support TypeScript or Flow not to mention that Vue’s lifecycle events are more clear cut than React’s.

Vue has only one person writing code. Not anymore.

Vue is for simple projects. Maybe you should read how Adobe is using it these days.

I am not writing this specifically for Vue but believe me that this simplicity can be found in other libraries as well e.g. RiotJS, StimulusJS etc.

Unfortunately, React and Angular have excellent marketing strategies, which plays a major role since they are trying to sell longevity instead of code happiness. By code happiness I mean the factor which make your developers happy to write code they understand and are proud they wrote it. With React and Angular I am not that happy, especially with React.

With Vue the selection was being made from a pool of 10+ team leaders because it just works as it should out of the box. Their vue-cli is also in the same league angular-cli is, but the difference is were angular could not operate very efficiently without, Vue could work without it with no problem.

Finally, I have to point out that lately among the majority Front-End developers, there is this strange notion that if your code is easy to understand, not very complicated and not using the latest ESxxx you are doing something wrong. If you look at Angular you have to learn RxJS, TypeScript etc. and even if you are not satisfied with this selection few will admit it. We have to get rid of the herd mentality and marketing strategy of 2–3 large companies and exercise common sense and independent spirit.

Working with HTML5 data attributes

Before HTML5, working with arbitrary data sucked. To keep things valid, you had to stuff things into rel or class attributes. Some developers even created their own custom attributes. Boy, was it a mess.

But that all changed with the introduction of HTML5 custom data attributes. Now you can store arbitrary data in an easy, standards-compliant way.

How do data attributes work?

A data attribute is exactly that: a custom attribute that stores data. They are always prefixed with data- followed by something descriptive (according to he spec, only lower case letters and hyphens are allowed). An element can have any number of data attributes you want.

Here’s an example using a list item to store data for a user:

Of course, this data isn’t very useful to a visitor because they can’t actually see it, but it’s wildly useful for building web applications. Imagine a delete button in your app:

All the data you need is right there to send to your backend script. No morerel stuffing or parsing IDs and actions out of other attributes. Data URLs make your life easier.

What can you store?

One thing to remember when working with data attributes is that you can’t store objects in them. Well, you can if you serialize them, but we’ll save that for another post.

For now, just know that you’re pretty much limited to storing strings.

Reading/writing data attributes with JavaScript

Using the delete button as an example, let’s look at how we can access this data with JavaScript.

Pretty simple, right? Now you can pass cmd and id to your app in an AJAX request or do whatever else you need to do with it.

Reading/writing data attributes with jQuery

Here’s the same thing using jQuery’s .attr() method:

Don’t get this confused with jQuery’s .data() method. Although there is some overlap in how data attributes and .data() work, they’re two totally different things. If you’re not familiar with it, just stick with .attr().

Using the dataset API

HTML5 actually has an API just for working with this type of data. Alas, IE10 and below don’t fully support it, but it’s still worth mentioning.

Using the button example again, here’s how to get and set data attributes using the dataset API:

Note how there’s no data– prefix or dashes here. Similar to the way CSS properties work in JavaScript, you’ll need to use camel case notation. The dataset API converts each one so you’ll always have data-some-attribute-name in your HTML and dataset.someAttributeName in your JavaScript. Magic!

Things you can do with data attributes

The examples above are very basic, but you can do so much with custom data attributes. Here are a few examples off the top of my head.

Filtering

Say you have a list of things and you want to filter them by keyword. Just put the keywords into a data attribute and write a short script to loop through and show/hide them accordingly.

Here’s a quick and dirty filter using jQuery:

Styling

It’s arguably better to use classes, but you can style things against data attributes too. Here’s how to apply a style if the element has a certain data attribute (regardless of its value). First, the HTML:

Now the CSS:

But what if we wanted to style it based on the data attribute’s value? This will work for any data-warning attribute that contains the word error:

Configuring

Bootstrap uses data attributes as an HTML alternative to configuring plugins via JavaScript. Here’s an example of a popover:

A better way to store data

Custom data attributes are widely used all over the web. The nice thing is that they work fine in older browsers, and they adhere to web standards moving forward. That means you can start using them today knowing that they won’t stop working tomorrow.

I’ve shown you a few common ways to use custom data attributes. What other uses can you think of? Have you used them before? Let me know by commenting below!

How do you know if you wrote readable and maintainable code?

Dissecting the question, we have two operative terms here: “readable” and “maintainable.”

Let’s talk about what these mean.

“Readable” would describe code that is understood without much inspection or explanation by another developer. You have to choose what parameters you want to describe the “other developer” to know what would be readable to them.

Some things are somewhat universal and limited by human factors. For example, few people can follow poorly named variables. (There’s your first heuristic – are there clear names for variables, classes, methods, and other references?)

Other things are a bit more nuanced. For example, if the developer uses the language you are writing in on a regular basis.

Or, is the developer familiar with the domain the project operates within? How experienced are they as a developer? Do they have a particular background that might make the code more or less readable to them?

But what if you don’t know who the other developer is?

This is why we develop standards, patterns, and best practices. For example, JavaScript code tends to use camelCase, so writing your code with camelCase provides a sense of fluidity (which plays into readability). Knowing the common patterns and style that the language typically uses is important. (As an additional note, your organization may have your own style defined; follow it.)

Some simple, practical heuristics to follow:

  • Use descriptive variable names. Longer variables are more easily read.
  • Use whitespace! Compilers and minifiers mean that whitespace is free. Take advantage of this.
  • Practice finding a balance between abstraction and practicality. You do not need 10 layers of redirection for simple tasks; start with the simplest approach and abstract during a refactoring process.
  • “Make it work, make it right, make it fast.” In that order. This will immensely help the readability of your code, because you start first from comprehension, and then move towards performance. This establishes your pattern and semantics up front, and you are more likely to maintain good semantics this way.
  • Know your audience. If your audience isn’t used to inline lambda calculations, skip it. Even if you believe it is the “best way” to solve the problem, there are other equally good ways most likely available.
  • Follow well-established refactoring and OO patterns. Seriously. These things have been tried and tested, and they work. Look here for a good description of many of these patterns: sourcemaking.com/design_patterns
  • Don’t follow rules blindly. Take some time away from the code and revisit it – what sticks out as weird? What sticks out as confusing? When does your brain feel tired?
  • Readable code isn’t always maintainable, and vice versa. Maintainable code is established by following good practices and principles.
  • Tests are HUGELY important to codebase maintenance. Having good test coverage keeps you from having to load all of the codebases into your working memory (in your head), and reduces errors. (Note: tests won’t eliminate errors altogether; they are there to help you, not to make you obsolete.)

All-in-all, coding is a human process. Follow Hemingway’s advice when writing code. Simpler is typically better.

Top 8 Signs Your Writing Bad Unit Tests

If you have been developing software for a long time, then you can easily relate to the importance of unit testing.  Experts say that most bugs can be captured in the unit testing phase itself, which eventually gets passed on to quality teams.  Here is a list of my top 8 signs your writing bad unit tests.

1) Test passes but not testing the actual feature

Believe me, I have seen test cases in some projects that appear to be doing lots of work in the code but in reality, they were doing nothing. For example – a test that’s sending requests to the server and no matter what the server responds with, the test was passing.

Beware of these such test cases taking place in your code repository by doing strict code reviews. Once they make their way in your code base they will become a liability on you to carry them, build them, and running them every time but without adding any value.

2) Testing irrelevant things

I have seen developers checking multiple irrelevant things so that the code passes with doing [something], well not necessarily the correct thing. The best approach is to follow the single responsibility principle, which says, one unit test case should test only one thing and that’s all.

3) Testing multiple things in assertions

In the previous sign, the test was testing irrelevant things. For this sign the unit-test is testing the correct items,  however, there are too many items in one test case. This again is a violation of the single responsibility principle.

Well, please note that I am not encouraging the use of a single assertion per test case. To test a single entity, you might need to use multiple assertions, do it as needed.

For example, one API which takes some parameters in a POST body then creates the Employee object and return it in response. This Employee object can have multiple fields like first name, last name, address etc. Writing a test case to validate only first-name, then another for last-name and another for the address is duplicity of code, without any value. Don’t do it!

Instead, write a single positive test case for creating the Employee object and validate all of the fields in that one unit test. Negative test cases should be written separately doing only one thing and one assertion in this case. e.g. One test case for blank first name, one test case for invalid first name and so on. All such negative test cases can be validate using a single assertion which expect an exception in response.

4) Test accessing the testee using reflexion

This one is real bad. Trying to change the testee to suit ones need.  The test will blow up when the testee may refactor some of the code.  Do not use this or allow to be used either.

5) Tests swalloing exceptions

I have seen my fair share of such test cases. They silently swallow the exception in little catch block at the end of the test case. And worse is that they do not raise a failed alarm. Exceptions are signals that your applications are trying to communicate that something bad has happened and you must investigate it. You should not allow your test cases to ignore these signals.

Whenever you see an unexpected exception, fail the test case without failure.

6) Test which depends on some excessive setup

I do not like test cases that require a number of things to happen before they start testing the actual thing. Such a scenario could be an application which facilitates online meetings. Now to test whether a user of a particular type, can join the meeting, below are the steps test is performing:

  • Create the User
  • Set user permissions
  • Create the meeting
  • Set meeting properties
  • Publish meeting joining information
  • [Test] User join the meeting
  • Pass/Fail

Now in the above scenario, there are 5 complex steps which must be setup before actual logic is verified. For me, this is not a good test case.

A correct test system will have an existing user present in the system for this activity, at least. This will reduce at least two steps in the test case. If appropriate, you could have a few already created meetings to make this test case really focused.

Another way to make it correct is by using mock objects. They are there for this very purpose.

7) Test compatible to only developer machine

This is not widely seen but sometimes visible when written by freshers. They use system dependent file paths, environment variables or properties in place of using common properties/paths.

8) Tests filling log files

This never seems to be an issue until you need to perform a deep debug then make life hell for debugger who is trying to find something hidden in those log files bloated with wasteful messages.

Tests are not for debugging the application, so do not put debug statements in your logs. A single log statement for Pass or Fail is enough. Believe me.

 

These are my thoughts based on my experiences. I do not expect you to agree with me on all of the above points or you might have some other opinion which is perfectly cool too.

Return of the Senior Engineer

To paraphrase Mark Zuckerberg, there is a widespread feeling that young people are smarter and senior developers are not needed. But, when you look inside most businesses, you see businesses that are being held back by a lack of senior developers.

What did the founder of one of the largest tech companies mean by this?

Many new startups typically take a year to produce something that is ugly, full of bugs, inflexible, poorly written and practically (but not absolutely) unusable. Then, in year 2, they re-write the entire product which is 10x better yet is plain, still full of bugs, still inflexible, poorly written in a different way and somewhat usable. Finally, in year 3, they re-write the entire product for the third time and, before it is delivered, the investors give up, the startup runs out of money and the startup folds.

This is one reason (but not the only reason!) that startup failure is so high. The startup built the wrong thing in the wrong way and paid the price in years of development time and millions of dollars of venture capital.

Differently, in the biggest tech corporations, the product just slows down and creeps along. After years, the product is reasonably attractive, has a “big” codebase and is not very flexible. New features are small and mundane, and, in the worst cases, simply visual (“a new coat of paint on an old car”). Developers add to the mass of code but simply don’t have the technical ability to see into the codebase and make the changes necessary to make big, new features possible.

First, is it reasonable to expect one senior developer unwind 2 years of design and code chaos, bring to heel a 10-person team of non-senior developers who continue to produce code and whip the product into shape in 6 months? Is it reasonable to hire Michael Jordan to lead your team of rookies in the mid-season and expect him, by himself, to win the NBA championship for you? Yet that’s what a lot of companies expect: that they can hire ONE person to supercharge an entire team or even turn nothing into something amazing.

At a startup, it’s possible that the right senior developer(s) could get the startup to year 2.5 in 1 year. Instead of having your developers finally producing a sell-able product just when it’s too late to matter, you can save a lot of time and some money.

At a big company, the right senior developer(s) can clean up your code base, make it possible to produce big, new features and actually produce big, new features. The focus should be placed on hiring those software engineers who have “experience” dealing with the software problem(s) you have and less about tossing warm bodies at the problem.

Great truths about computer programming

After sitting around with a few programmer friends of mine we came up with the following truths about computer programming.

  • Programming is 99% self-taught. See all that stuff you learned in that Python class? Yeah, you’re going to relearn it all when working on a real project.
  • There’s no such thing as a simple bug. A stupid mistake like leaving out a semi-colon or misspelling a variable name can easily take a week to find and fix and can cause significant loss of sleep.
  • The more code you write the more you shut up about what’s possible and what’s next to impossible. And the more you pity those newbies with that “Of course it’s possible!” mentality.
  • The language you use doesn’t matter. There’s so much fuss about which language is better for x or y. At the end of the day what matters is can you solve the problem? As a company manager, I’ll want to see a running system. Not a running (insert language name here) system.
  • Six months later, you wouldn’t recognize your own code. Documentation and comments are more of a survival tactic than niceness to whoever encounters it next.
  • Programming isn’t sexy at all. Try taking that girl home by telling her your heroic tale of saving an entire department by rewriting a recursive function to take advantage of a feature in the new server Intel chips to scale up their online orders. Then tell me how it goes.

Why do programmers wear headphones while working?

There is one critically important reason to wear headphones while programming. When you understand the impact of this, it will change how you think about what it means to make things and what that process really requires.

Programmers wear headphones so that they won’t be bothered. That much is pretty obvious. The reason why being bothered is an issue is something I’ll get to in a moment.

You see, the modern workplace is designed to ruin programmer productivity. If I were to design an office space to maximize programmer output, it would look like the opposite of nearly every modern office space I’ve ever worked out of.

Actually, I now work in an office that basically maximizes my potential output as a programmer and it really does look like the opposite of most modern corporate offices.

The big gimmick right now in office space design is “open office spaces”. This is designed to improve collaboration (as if that is the great problem of modern work).

Open office spaces really exist so that it looks like everybody is busy working. It looks cool to see so many people busily walking around, talking, and in general looking busy. There is a sound component to it as well.

Open office spaces are loud!

But again, it looks and feels like an improvement over the previous decades’ bad idea – cubicle farms.

Also, open office spaces are cheaper than cube farms, so companies are saving money while making everybody look busy (even at the cost of huge productivity decreases).

In general, all of this is terrible for the actual act of programming.

The art of programming tends to rely on the same thing most art relies on – flow.

Getting into the “flow state” where you are focused on a problem deep enough to make connections and leaps and do your best work without “thinking” is where the real magic of programming happens. This is very similar to playing music, writing, and painting.

Imagine if Leonardo da Vinci was expected to paint the Mona Lisa in an open office space while his coworkers and manager would stop him mid stroke every 15 minutes to ask a question. Would he have ever painted it?

No, I don’t think so.

And yet, programming is a creative process that requires a similarly creative environment as most other art does.

Take authors as a similar example. Stephen King doesn’t “collaborate” to write his books. He sits down at the typewriter or keyboard and starts writing. Imagine if he had to do a daily standup about his latest few pages each day with a committee of his peers.

His work would suffer.

It turns out that to code well we rely on that same kind of process of getting into the flow and doing creative work with our minds. It’s how our brains seem to be wired for creative work.

People like Paul Graham have written about Makers Schedule vs. Managers Schedule before with a similar understanding.

It takes something like 5–30 minutes to get into a flow state. If uninterrupted, time distortion kicks in and a couple hours fly by and a bunch of code is created.

Every interruption resets the clock on that process.

So, what programmers need to maximize flow (and thus output) is blocks of 2–4 hours without interruption. Ideally, a whole day without interruption would allow for as many as 3 or 4 blocks of “flow”.

As near as I can tell, the average programmer tends to only get maybe one flow block a day. Sometimes a really diligent programmer will manage two or three flow blocks a day, but that doesn’t happen very often from what I can tell.

Headphones, especially noise canceling headphones (like the ones I’m wearing right now), are an effort by programmers to block out interruptions and stay in a flow state.

With open offices, email, slack notifications, coworkers tapping you on the shoulder, and so on…

It’s almost impossible to get to a flow state as a programmer.

So, my advice to you is simple. If you are a programmer trying to maximize the total productivity and flow blocks each day, wear headphones, avoid meetings, don’t check email, turn off slack, and basically go into a cave and write code.

And if you don’t have the option to do that, accept the fact that you might only be able to get one flow block a day and plan accordingly.

The typical stages in the career of a software engineer?

The career of a software engineer is not an easy one. It’s a tale of hardship and woe, filled with ladders to climb, and management to appease.

Level 1 (0 – 2 years):

You just graduated from college, a young boy with a young boy’s dreams, big eyes and a thirst for life. You start your work hoping to change the world, invent the next big app or make enough money to retire young and spend the rest of your life on exotic beaches, sleeping with models, who have a thing for nerds.

The first few months seem very alike, you’re assigned the same tasks every day, and your only job is not to screw up big time. It’s not what you were hoping for, giving your superior level of intellect and mad skills on the keyboard, but you’re certain that soon enough things will change.

You wake up one day after two years and realize that you’ve been living the same day and writing the same code over and over again. It makes you sad, but you feel a wind of change coming.

Level 2 (2–5 years):

You’re no longer a junior developer now, you’ve been promoted to a full-blown software engineer, basically a rock star, without the money, women, and fame.

You’re no longer being supervised by that old mean engineer who hates you because he knows you’re a better coder than he is. You’re being assigned small tasks, which you accomplish flawlessly -most of the time- and you can finally start feeling valued and useful. Everyone respects you now!… right?

Level 3 (5–10 years):

You’ve been doing this long enough now to be called a senior developer and assigned your own team. You’ve long have given up on your dreams to change the world, sleep with models or even make the next big app, after years of seeing people try to do it and fail, and having tried yourself to launch something and failed at it too, though you wouldn’t admit it, and hide behind the excuse of not giving it much attention or that people are not ready for your creation yet.

On the bright side, you get to handle big projects now and manage your team the way you want to. You also make a lot of money, which is what you always hoped for! But on the downside, you’re honestly not into coding that much anymore, your team is a bunch of brats who constantly think they’re better than you, without realizing you’ve been helping them grow all along, and you’re very sure they see you as the old mean guy who’s there to make their life hell, oh! And although you do make a lot of money, almost half of it goes to pay the rent or mortgage, because you had to move to an expensive city to get a big offer.

Level 4 (10–20 years):

At this point in your career, you have a choice to make, either you join management and become another suit who’s only concern is cutting corners to save money, and to meet this quarter’s earnings expectations, or to continue being a developer, who’s work now consists of managing multiple teams and making sure everyone’s doing their job.

You were always a rebel, you chose to code because it gave you freedom, heck, you wrote your best lines listening to Rock and Roll, so I’ll assume you’d go with continuing on your path as a developer.

It’s been years since you enjoyed coding or even went to the office excited about something. Last night you looked in the mirror and saw your empty dead eyes looking back at you, and you couldn’t help but remember the young boy with dreams and hopes who came into work with a big stupid smile and shiny eyes, and you decide to do something about this. You realized that just because you didn’t get everything you wanted, it doesn’t mean that your life or career was not fulfilling, and maybe its time for you to move on, and to start giving lectures or maybe even take a teaching position, to make sure that the newer generation does not end up the way you did.

Level 5 (20 years+):

At this point, you discover that you’ve been granted the powers of an almighty wizard, by the benevolent gods of coding. You magically turn to 24 again and have a spell for infinite money.

You get your happy ending after all, and you spend the rest of your life on exotic beaches sleeping with models.