Monday, October 3, 2016

I started this blog 3 years ago with the desire to use it as forcing function for staying relevant in the software industry. As I have been thinking through what it means to succeed in the software industry I've been writing those thoughts down and sharing my imperfect view of the industry with you.

Over the last 3 years I've published 152 posts and had the pleasure of having had 38,000+ readers (that I know of). To that end I feel like I've accomplished what I started out to do. This blog, for the most part, has focused less on opinion and more on learning. I've been able to cover topics such as fundamental data structures, mobile development, as well as leadership and career development.

While this blog has been a great source of joy for me, it's also been a time suck and source of stress making sure I have something ready to post Monday mornings. It's time to take a break. I don't know if it's permanent or temporary. But my goal is to just relax a bit and spend time with my family.

Monday, September 26, 2016

As humans, none of us is perfect. Even if we can, on occasion, execute perfectly on something more often than not we all need to course correct at some point. Some examples of when we need to course correct are:

Having incorrect or invalidated assumptions

Starting something that has a lot of ambiguity

Finding out about missing or hidden dependencies

Having a plan that falls short of delivering on a specific commitment.

Failing to accomplish a goal, milestone or key deliverable

That list isn't exhaustive and is applicable to the projects we work on, the way we interact with our peers/directs/superiors, career development and many other aspects of our lives. Having mechanisms in place to help you correct your course *before* or soon after you get off track will help you be more successful. Here are some tips to help you setup mechanisms that enable course correction.

Be willing to change course

As humans change doesn't come easy for us. Once we set ourselves on a certain course we will naturally want to continue down that course because it's easy. This may sound obvious, but course correcting starts with being willing to change course.

What this means practically is that you have to be open to:

Being wrong

Doing more work

Scraping work you've already done

Having difficult conversations

Asking difficult questions

Being relentless about seeking the truth and proceeding with the *right* data

Ask questions that help you understand when course correction is needed

There are several questions that I try to consistently ask when checking in on the progress of something I'm working toward:

Where am I on track?

Where am I ahead of schedule?

Where am I behind schedule?

Is there anything I plan to work on that I no longer need to?

Do I need to re-arrange priorities?

Is what I'm working on right now the simplest/fastest/most efficient way to achieve my goal?

What information do I have now that I didn't when I started? How does that change my approach?

Is everything I depend on to be successful still on-track? If not, what does it take to get back on track?

How does the recent decision about X affect me?

Meet regularly with your key stakeholders and solicit feedback

Making sure that you're on the right course means talking with your stakeholders often. Depending on the context of what you're trying to achieve, the form of these meeting may look different. But the key is that you're meeting regularly and getting as much feedback as you can.

Some common forms these meetings take are:

One-on-ones: This is where you are meeting with an individual regularly and asking for specific perspective and feedback. These meetings are more intimate and can typically get into a lot of depth. These typically occur weekly or bi-weekly.

Daily project sync up: Most agile teams do this in the form of a daily scrum. The purpose of this meeting is to make sure everyone is aware of hyper local changes. Talk about what was accomplished yesterday, what you plan to accomplish today, and what you may be blocked on.

Program status meetings: This is where you meet with the key participants of a project or program and check in on the status. In this meeting you want to focus on things that are either off track or at risk of being off track. Most often I've seen this occur weekly or bi-weekly. It's really important to have people in this meeting who can authorize change.

Stakeholder meetings: These are regular sync ups with the people that depend on you and your work or that you depend on. These meetings are typically with people that you don't have much visibility into day to day operations with.

Team/Org meetings: This is time with your direct team. This time is best used for vision casting, transparency, and/or checking the temperature of the team (i.e. how are people feeling).

Monday, September 19, 2016

Most of the software development shops I've worked at in my career didn't have developers deploy their own code. Typically the developers would create a release and hand it off to QA who would do some combination of manual, automated, and performance testing. When bugs or performance issues were found they'd send the release back upstream to developers who were already working on the next feature.

This creates a culture of fear that the production system needed to be protected from the developers. This is unhealthy in my opinion. Software development teams should be deploying their own software for four main reasons:

Ownership

Accountability

Insight

Continuous Integration/Continuous Deployment

Ownership

Software teams that deploy and maintain their own software in production tend to have a higher level of ownership. This is because they are involved in the full end-to-end software development life-cycle rather than just building the software. They become better aware of the machines (whether physical or virtual) that their software runs on. They're more likely to insist and push for deployment automation as developers tend to hate repetitive manual tasks.

When the developer isn't responsible for deploying their code they move on to the next problem space after they've "shipped" their code to operations. This typically means they've moved on both mentally and emotionally from that release. When a developer is responsible for pushing to production they're invested in the release getting all the way to customers. They become responsible for diving in and solving problems that pop up during deployment.

Accountability

When you're responsible for maintaining software in production, you're more likely to be accountable to what happens in production. Specifically, the dev team becomes more accountable to:

Bugs

Test coverage

Deployment failures

Poor performing code

When you work at scale there are often bugs that only show up in production. When developers deploy to production they become more accountable for fixing bugs, performance issues, and deployment failures as they are directly exposed to them during the release cycle. One thing I've seen successful organizations do is, when a release fails, block all further releases until the deployment succeeds. Developers that are accountable for these failures will be encouraged to fix them because they're prevented from moving on to the next new thing until the current thing is successfully deployed.

Insight

Understanding the health of your system means having the right metrics and validations in place. When software developers own deploying to production they're more likely to instrument their code well because they will need to validate that their deployments are successful. In my experience teams that deploy their own code better understand the performance characteristics and health of their systems. They are also better able to diagnose problems because they're familiar with the differences between their development and test environments and the production system.

Continuous Integration/Continuous Deployment

When a team owns their code end-to-end they are setup for success with respect to continuous integration and continuous deployment. They don't have to jump through hoops in getting their code into production and they can integrate deployment and test tools directly into their development pipeline. This encourages them to ship smaller features more often. By doing this, they decrease the time it takes to close the feedback loop and are better able to adapt to their customers ever changing needs.

Monday, September 12, 2016

Recently I was watching the film Hector and the Search for Happiness and it got me thinking about how work can either be a source of happiness or contribute to a sense of unease or unhappiness with your life. There are a few quotes from the movie which I think should be examined in the context of your job and your overall happiness.

Making comparisons can spoil your happiness

Even if you work at a company that stack ranks it's employees, you are not your peers. While looking to others and their accomplishments can be a great source of inspiration, comparing yourself to others can also be an easy road to unhappiness.

Instead of comparing yourself to specific people, who may or may not have the same gifts and talents as you, figure out what achieving and exceeding your goals in *your role* means. This means sitting down with your boss and having a conversation about the expectations of your role and what your goals are. I highly recommend creating SMART goals.

Work towards achieving *your* goals and not towards being better than your peers. If you consistently achieve or beat your expectations it won't matter if you're better than your peers. You'll feel valued and appreciated and likely will be rewarded for your effort.

Many people only see happiness in their future

Are you one of those people that only seems to be happy if you know you're on track to a promotion or a particular set of responsibilities or ownership? Having an aspirational goal is great, but if it's the only source of happiness at work it's getting in your way more than it's helping.

What is getting in your way of being happy right where you are? Make a list of the top five things in your current job that are getting in the way of your happiness. Then create a set of goals for each one to affect real change in your current role.

For example: let's say you have a co-worker who is driving you nuts. They're overly critical of your work and you feel like they're targeting you in an unfair manner. Set a goal to try to dig deeper into the tension and try to see your interactions from *their* side. Be blunt and honest and tell them you feel tension and would like to resolve it. You'd be surprised how much unhappiness in your current situation is resolvable simply by bringing it up.

Fear is an impediment to happiness

What fear is causing you to dread going into the office? Is that fear rooted in reality? The typical work related fear I experience is not feeling like I am on the same par as my peers. I'm afraid that I have to work harder than them to get the same thing or less accomplished. But at the end of the day this fear usually turns out to be baseless.

I've found that the best way to root out fear at work is to work closely with your manager and your stakeholders and define what success looks like. Your manager should be able to paint a picture of what success in your role looks like. Very likely, this will start with a job description or some internal HR document that describes the necessities of your role. Talk with your boss about that and ask for specific examples of meeting those expectations or exceeding them in your current projects. You should do the same with your project stakeholders. Make sure that what you're planning to deliver is what they're expecting you to deliver.

You're likely going to spend 2000+ hours a year at work. Why not make it a source of joy?

Monday, September 5, 2016

We use writing in all aspects of our lives whether it's an email, a text message, a blog or something else entirely. Writing is one of the most powerful mediums we have in communicating our ideas. Given that, it's important for you to understand how to communicate effectively.

Understand what you are trying to achieve

Before you communicate in writing you should clearly understand what you are trying to achieve. Are you trying to disseminate information? Are you making a call to action? Are you soliciting information? Understanding this will help you better frame your narrative such that you can effectively achieve your goals.

Lead with the call to action

This is akin to putting the most important information first. Your reader shouldn't have to hunt for what you're asking them to do. You should be explicit up front about *what* the call to action is and then provide more information as to *why* you're calling them to act.

Someone familiar with the problem space should be able to stop reading after the first few paragraphs or the first page and grasp the main point of the text. Your reader should only have to dig into the back story if they want. Providing too much context can get in the way of what you're trying to achieve. On the flip side, not providing enough context can leave your reader with more questions than when they started. If you layer in the context you give your reader the ability to choose if they have enough information or if they need to keep reading.

Footnotes: Writing is a unique medium that allows you to point out where your data comes from in such a way as to not distract from the main point. Footnotes give you the opportunity to back up your narrative with facts, but allow you to layer them in such that the reader only has to read what they care about.

Appendices: If you have a lot of context that is important but not primary to the narrative, throw them in an appendix. The curious or skeptical reader can go and dig more into the *why* of your narrative without you having to detract from the flow.

Read it out loud

Proof reading silently make it very easy for your mind to skip over something that you've spent a good amount of time on. Proof reading out loud allows you to find areas where the narrative doesn't flow. It also gives you the opportunity to figure out where you have too much or too little information.

Monday, August 29, 2016

In the first decade of my career I wrote software in C++, Java, C#.Net, Ruby, Python, Objective-C, VB 6 and VB.NET. Additionally I developed for ASP, ASP.Net, and PHP based Web Sites as well as scripted in Powershell and Bash. Learning multiple programming languages was very helpful for me during my career as a software engineer.

Here are some reasons that you should learn multiple programming languages.

Trains you to separate the engineering from the language

Learning multiple languages teaches you to explore design patterns and engineering best practices that aren't platform or language specific. Being a great software engineer is about being able to identify the correct algorithms to solve your problem and being able to implement that algorithm in the language and platform that best solves the problem. Great engineers are able to build simple software and use design patterns that are language agnostic.

Enables you to learn other languages more easily

Once you've started to learn to identify design patterns learning a new language becomes less steep of a learning curve. Learning a new language is about learning the plumbing of the language, i.e the syntax, the libraries, and the run-time. Knowing what you *should* be building allows you to learn *how* to build it.

Exposure to different tool-sets and platform features

As you learn new languages and platforms you'll also be exposed to new tool-sets for building, debugging and testing your software. Using these different tools will help you to learn different aspects of interfacing with hardware and other software as the languages and platforms will likely have different layers of abstraction for different things. For example with C++ you'll learn better memory management. Whereas with Ruby on Rails you'll learn dependency management with tools like Bundler.

Become better at picking the right tool for the job

Learning the ins and outs of different languages and platforms will help you learn to pick the right tool for the job. You'll understand what languages excel at what types of problems. For example, you may need to write a script to parse files and find that perl's built in regular expression capabilities help you to write an efficient and simple script. You may want to build a cross platform game and decide that using C++ will help you port your game to multiple platforms without as much code duplication.

Monday, August 22, 2016

In almost every industry, but especially in the software industry, there's always enough to do that you could work 24/7. But that's not healthy for you or for your company. Not having a healthy work/life balance contributes to burn out, discontent with your employer/boss/team, and often general depression. Obtaining work/life balance is not like capturing a unicorn. It's not a myth. It just looks different depending on what your priorities are.

Different phases in life require different types of work/life balance in order to obtain satisfaction in life, achieve your career goals and prevent you from burn out. For example, when you're single and kid free a lot of your satisfaction in life comes from your day job. You'll want to invest longer hours because you'll be rewarded in both your life satisfaction and in your career growth. Contrast that with someone who is married and has kids. More of their life satisfaction will come from outside of work than from inside. They'll be trying to do a good job with their spouse, their kids, and their jobs.

Here are some tips that have helped me achieve a good work/life balance.

1. Set The Correct Expectations With Your Management Chain and Your Peers

You want your boss and your team to know they can count on you. But that doesn't mean that you have to be available 24/7. Have a conversation with your boss and let them know explicitly what to expect your in office and out of office hours to be. Understand that this is a two-way conversation and your understanding may be incorrect. Having this conversation will make sure that both you and your boss are on the same page.

For example: my son goes to sleep around 7 pm each night during the school year because he has to get up at 5 am. It's important for me to get an hour with him at night before he goes to bed since I don't see him in the morning. So, I sat down with my boss let him know that my goal was to try to leave the office each day between 5 pm and 5:30 pm each day because it takes me 30-40 minutes to commute home. We talked through this expectation and my plan to be in by 8 am each day. I also let him know that I am flexible and can occasionally stay later if the need arises, but that I it has to be the exception to the rule.

Knowing my goal helps me coordinate better with my boss. He knows that if something comes up after 5 pm that I will likely address it the next morning. He also knows that if something exceptional comes up that is important that he can count on me to address it.

2. Be Willing To Jump In As The Exception To The Rule

Most high tech companies have core business hours but the internet doesn't stop because it's 5 pm. Working in an industry which doesn't have an open and a close means you'll need to be flexible in your schedule and occasionally work before or after your normal day begins or ends. If you're working on a project with a tight deadline you're going to need to be flexible and willing to put in additional hours in order to maintain a good work/life balance as the standard rule.

3. Understand The Trade Offs and Be Willing To Accept Them

Different industries require a different level of commitment. For example, retail organizations are likely going to require you to work on or around the holidays. Why? Because that's when some of their core business during the year takes place. It's not reasonable to take a job in retail and expect to take Black Friday, Cyber Monday, or Christmas week off.

That's just one example. Each industry will have different trade-offs. Some will require travel. Some will require work on the weekends. Some will require long hours for a couple weeks out of the year during planning periods or before big products ship.

If you understand the trade-offs of your industry then it won't feel like your work is constantly encroaching on your work/life balance. It'll be a conscious choice you've made where you've deemed the rewards to be greater than the demand. You and your employer will have the same understanding of where the balance between work and life is and what reasonable and unreasonable expectations are.

4. Remove Work Email From Your Phone

This one has helped me significantly. At first I didn't have a choice as my work stopped allowing Android phones to connect to our email servers due to the Stage Fright vulnerability. The first few months I went through withdrawal and was afraid that I was going to drop the ball on something. But as I learned to set expectations with my boss and my peers I slowly started feeling more comfortable being disconnected.

In my case, I've explained to my management chain that I don't have access to email on my phone and didn't plan on VPN'ing in to check it while at home. But I also told them explicitly that if something came up to please feel free to text me. This gives them confidence that I'm not going to just fall off the face of the planet when I leave the office and it helps me to feel okay not being connected 24/7 to my job.5. Exceed Expectations When You Are At Work

If you exceed expectations while you're at work then you'll build the trust that you need for your boss and peers to understand you will get the job done. Your boss and your peers will believe they can count on you to get the job done and won't feel like they need to micro-manage how or when you do the job.

Exceeding expectations assumes that you know what the expectations of you are. You *must* sit down with your management chain and have this conversation. You *should* have goals that are clearly defined. You *should* also talk to them about how to escalate to you on off hours. For example, if there's an expectation that sending you an email is enough to engage you after hours but you don't check your email after hours, then you're not going to be able to exceed expectations.

Monday, August 15, 2016

The software industry is largely made up of highly intelligent and highly analytical individuals. It's an industry where experience, ideas, and intuition help set people apart. We celebrate innovation, creativity, simplification, reuse, use of patterns and avoidance of anti-patterns but if not careful we can encourage a culture of fear.

Being Afraid To Be Wrong

Being wrong is often viewed as not being good at what you do. In an industry where your intellect and your intuition are your primary tools to be successful, being wrong can make you feel as though you're not as intelligent or as capable as your peers.

But this is a fallacy. The most intelligent and most intuitive people I've worked with in the industry are able to differentiate and admit when they're wrong. Being able to recognize when you're wrong and pivot to the right path is a skill that sets the highly capable apart. It's a sign that the person is truly looking for the best solution, rather than the best solution they can create.

Being Afraid To Try Something New

The software industry is constantly changing. This can be unsettling to people who feel like they're constantly trying to keep up with the latest and greatest in technologies, frameworks, and platforms. It's often the case that the latest and greatest is really just a passing fad. Getting caught up in one of these fads can have negative impact on your team or your project depending on how much you've embraced the technology.

New technologies and new ideas always come with risks. You risk adoption being so low that the tech will fail, security vulnerabilities, scalability problems, and a whole host of problems that can come with new tech or new ideas.

The problem with over-indexing on the risks is that you'll miss out on the game changing technologies and ideas. You miss out on things like Agile development, CAP theory in distributed computing, Linux, Node.js, native Mobile apps, and much much more.

Being afraid to try something new means you run the risk of being left behind and becoming irrelevant.

Being Afraid To Fail

Failure is a very important part of progress. Being afraid to fail is tantamount to being afraid to make progress. Often, people are afraid to fail because they believe that if they do they're not going to have another chance to succeed.

The real problem isn't failure, it's the scale of the failure. Waiting too long to validate your assumptions is a recipe for disaster. The key to failing well is to limit failures scope and to learn from it. If you can create an environment that leaves room for failure, you're creating an environment that can be successful.

Monday, August 8, 2016

This is one area that used to be a real struggle for me earlier in my career as a software engineer. If you asked me what motivated me, I would give you the *right* answer. I would tell you that I was motivated by solving interesting problems, which was (and is) very true. But it wasn't the whole truth. I was (and am) also motivated by moving up the corporate ladder and having a bigger and bigger voice at the table (meaning my voice being able to carry a lot of weight).

I thought that admitting that I wanted to move up the corporate ladder would mean that (1) I was greedy or selfish, (2) would only have my actions only interpreted through that lens or (3) would mean that I had an ego or a self-inflated view of my skills or abilities. I didn't want to be construed as having an ego and I didn't want to be viewed as *that guy*. You know, the person who people say "he's only concerned with moving up the ladder and doesn't really care about the people he works with or how many bodies he leaves in his wake". Avoiding that persona was VERY important to me.

I was afraid to admit to myself, my peers, and my bosses that I wanted to get promoted, that I wanted more responsibility, that I wanted to take risks, and that I felt I was as capable or more than my peers to lead a project. I thought that if I just stayed heads down and executed on what I was asked to do that it would lead me down the path I wanted to go.

In some ways it did and in other ways it didn't. My effort did lead to a year over year increase in salary (and bonus depending on the company). I did gain the respect of my peers and have grown a reputation as someone that delivers on what I'm asked to and as someone who is disciplined. But it didn't lead to the leadership opportunities that I wanted.

I've been blessed with some natural leadership talent. I'm able to communicate clearly, I have good intuition and understanding, I generally want to help others succeed and I am able to take complex problems and simplify them. I assumed that other people would recognize that because i had these qualities that I *wanted* to be given opportunities of leadership with more and more responsibilities.

But those opportunities never came and 10 years into my career I realized that I was not where I wanted to be. At that time, I had been at my company for 5 years and decided that the only way I would move up the career ladder was to quit and find something else. When I did and put in my resignation the VP at my company was shocked. I told her that I wanted to move from an IC (individual contributor) role into a management role. And what she said next surprised me. She said "why didn't you just say so?" and went on to tell me that she thought I would be great at it but since I hadn't expressed interest wasn't ever considered for the roles that would come up.

And that's when I learned, it's okay to ask for what you want. If you don't it's more likely than not that other people *wont* know you want it, even if they think you deserve it. Since that conversation I've been very honest and straightforward with my career goals and I have been able to achieve them systematically (still working on several).

If you haven't already, sit down with your boss and talk about what your real career goals are. Be prepared to hear constructive criticism and be ready to receive it, learn, and grow.

Monday, August 1, 2016

No matter what your profession or what your role is in your company you alone are not going to be able to achieve everything you want or need to without the help of those who are higher on the corporate ladder than you. In the course of your career you're going to need the buy in, sign-off, and/or advocacy of your superiors to fully accomplish your goals. As such, managing up is a key skill to learn to be effective.

Here are some tips to help you be more effective when managing up.

Know what you're audience values

You're more likely to achieve your goals if they are aligned with the goals of those you need buy-in, sign-off, or advocacy from. So the first step in managing up is actually understanding the goals of your superior. Understanding their goals will help you understand how to motivate them to help you accomplish your goals. In trying to understand their goals try to find the answers to the following (in no particular order):

What are their near, mid, and long term plans for their customers?

What are the current challenges they are facing?

What role does your team or project play in their plans?

What trade-offs have they recently had to make?

What are the outside influences to their plans?

What defines success for them?

Be willing to change how you accomplish your larger goals

It's important to understand where your goals align and share commonalities and where your goals are at odds. When your goals are at odds you need to decide if (1) your goal is really crucial to your overall plan or success or (2) your goal is merely a stepping stone that can be achieved in another way which is more inline with the other persons goals.

Help to connect the dots between your goals and their goals

When your goals are complementary you need to bring that to the attention of the other person. Help them draw the lines and see the connections between your two goals. Help them understand that by helping you achieve your goal that they are really moving towards achieving their own goal.

Give options

Decisions are not often black and white. There are usually compromises and/or concessions that can be made that allow you to both deliver enough of what you are trying to accomplish to make it worth while. This is often done by providing options and their various outcomes to your superior. When doing this you want to be clear about what the concessions are and what they are getting and not getting with each option. The main goal is empowering your superior to help you.

Don't just come to a superior with a problem, come with a problem and the various possible solutions and their outcomes.

Make a recommendation that is backed by data

You need to have data that backs up the various options and their outcomes you are laying out. Hard data allows you to help them approach the problem more objectively. This is especially important when what your managing up is not something the person current envisions or thinks they want. It's important to make sure the data your bring is focused on outcomes. Good data speaks to the effects things are going to have on future projects, road maps, moral and attrition, return on investment and opportunity loss costs.

Monday, July 25, 2016

As a leader, regardless of what industry you're in, mastering the skill of delegation is a must. You cannot scale as a leader unless you are able to delegate the ground work to others. Successful delegation requires a certain amount of trust. But blind trust is the enemy of successful delegation.

Successful delegation means being able to trust that the person you are delegating to is capable, competent, and willing to get the job done. The best way to ensure their success is to follow the trust but verify model. In this model, you follow up with the delegate periodically to determine if:

The task is on track

The delegate is looking around corners. i.e. identifying what's coming up that's not directly in their line of sight

The known unknowns are being addressed

The delegate is working to identify the unknown unknowns

One common problem with people trying to implement the trust but verify model is micromanagement. Here are some tips for practicing trust but verify and avoiding micromanagement.

it's okay for it not to be done your way

In most cases there are many ways to solve a problem. Yours may or may not be the best way. Giving your delegate room to figure this out is important. Your primary role in the trust but verify model is to make sure that they:

Have thought through the problem and aren't just going off the cuff

Aren't making irreversible or hard to reverse decisions

Aren't falling behind schedule

Are aware of the decisions they're making, specifically with regards to long term sacrifices for short term gains

focus on the outcome

When making sure that the person you've delegated to is thinking through the problem it's important to make sure your questions are focused on the outcome of the task and not on the approach. Remember, you're not solving the problem and therefore the approach may not be the same as if you were solving the problem.

Focusing on the outcome of the task makes sure that whatever the approach, the correct result is being achieved.

understand how to measure success

As you delegate tasks or projects to others you need to be clear about what the definition of done is. Additionally, you should talk with them about milestones that can be defined and achieved before the task or project is complete. Use these milestones to measure the success of the task or project. The best way I've found to do this type of measurement is to create SMART goals.

Monday, July 18, 2016

Understand you're part of a larger system, and are not the center of that system

Your team, your software, and your role are crucial for the success of your company or division. But it's important to remember that you're not THE ONLY thing that lets your company or division succeed. You're one part of a larger ecosystem. Knowing this will help you identify:

Your role and your teams role in the ecosystem and how best to contribute.

What inputs/outputs are needed from you and your team to make the larger system better.

Where you may be a bottleneck to the success of the system.

Do the right thing, not because you're rewarded, but because it's the right thing

Good leaders understand that you're not always going to get rewarded for doing the right thing, but you still need to do it (whatever it may be). Doing the right thing may actually mean you have to take on more work. It may mean admitting that you were/are wrong. It may result in not achieving expectations. Whatever the outcome, it's about doing the right thing because it's right in and of itself.

Make time to step away and remove yourself from the problem space

If you're constantly in the thick of things you're going to burn out, you're going to get sloppy, and you're going to miss key things. You need to make sure that you are giving yourself time to pull back and think through problems.

I'm not just talking about vacations (which are important). I'm more talking about making sure you have built in distance from the problem so you can think. For me, this often happens when I'm riding my bike to or from the office. I have 35 minutes where I don't have anyone asking for my help or input. I'm not being barraged with email or phone calls. It's just me, the road, and my bike. It allows me to take time to think through things critically.

Surrounded yourself with advisers

Good leaders understand they don't have all the answers. But they also know how to get to the right answers. They do this by surrounding themselves with advisers who are subject matter experts on problems that they will never have enough time to become an expert in. For example, the President of the United States has his cabinet and the joint chiefs. These are people whose job it is to know the answers to problems that the president is accountable for helping to solve.

Hold strong opinions very loosely

Good leaders have opinions and are willing to express them. This doesn't mean that good leaders are arrogant. Quite the contrary. Good leaders are able to recognize when their opinions are wrong and are able to adjust. But they're not afraid to go out on a limb and express what they believe is right.

Monday, July 11, 2016

Software Engineering interviews can be stressful. They're typically 4 - 5 hours long meeting with 4 - 6 different people. Being prepared can be the difference between getting that job you've always wanted or failing to truly demonstrate your capabilities and skill-set. Here are some tips for preparing for software development interviews.

Make Sure You Understand The Problem, Ask Clarifying Questions

One of the bigger problems I often see in interviews is the candidate just jumping in to solve the problem without making sure they understand what they're being asked to do. Even if you feel like you understand the problem 100%, you should ALWAYS repeat back what you think the problem is before jumping in.

Every problem comes with some level of ambiguity. As you repeat back the problem think about how to remove that ambiguity. Ask clarifying questions that help you understand what is in scope and out of scope for the problem.

Review Your Data Structures

One of the main things that you need to be able to demonstrate in any software engineering interview is how well you 1) know your data structures 2) know when to use certain data structures and 3) understand the systematic complexity for each one (e.x. how long do reads or writes take). Before every interview you should review the following data structures and understand how to apply them to solve real world problems.

Array

Linked List

Hash Table

Binary Tree

Queue

Give An Overview Of How You're Going To Solve The Problem

To be successful as a professional software engineer you need to be able to communicate well. It's not enough to simply be able to code. Because you're going to work on a team and with people that aren't engineers (product development, program management, design, and etc) being able to communicate effectively is an essential part of the job.

Being able to talk through your solution helps you demonstrate that you're able to communicate effectively. Additionally, talking out loud about a solution often helps you identify gaps or potential bottlenecks before you get into your code. Essentially, it gives you a chance to validate your design and show the interviewer that you can approach a problem systematically.

Focus on Solving The Problem First Then Optimize

Another common mistake I see interviewees make is getting so focused on giving the most optimal solution that they never finish creating a valid solution. You're not likely to get an offer if you can't complete the exercise within the time allotted.

Your goal should be to create a working solution first. At that point, if you have time, you can optimize it. Along the way you can point out potential bottlenecks or un-optimized code.

Keep Things Simple

Simplicity in software is a gift. Complex software typically has problems with readability, understandability, and scale. You should focus on demonstrating that you understand how to keep things simple when solving your problem.

Some easy ways to do this are:

Limiting the number of classes/interfaces you create.

Use meaningful variable names.

Encapsulate the code into short simple methods, rather than one giant method.

Use built in language constructs rather than re-inventing the wheel.

Know How To Test Your Solutions

Professional software engineers test their own software. You need to be prepared to identify:

Test cases when the code should succeed

Test cases when the code should fail

Test cases that handle typical edge cases like NULL values, being passed 0, 1, or many objects, no connectivity, and etc.

Monday, July 4, 2016

Interviewing in the tech industry is hard. Both for the interviewer and the interviewee. As an interviewer you've got 45 minutes to 1 hour to determine if someone has the right technical prowess and is a good fit for the company and for your team. As an interviewee you've got 45 minutes to an hour to show off what you know, how well you adapt to change, and how you respond when you don't know something.

In my 16+ year career I've been on my share of bad interview loops. The reason they were bad wasn't because of anything inherent about the person conducting the interview. They were bad because the person conducting the interview didn't know how to flush out what they needed to know about the candidate because they were asking the wrong questions or questions with the wrong focus. Here are four ways I've seen interview questions go down the wrong track.

The Problem Requires More Than 20 Lines of Code

Writing code takes time. But even more so, solving the problem takes time. You need 3-5 minutes to go over the problem. The candidate then will likely 5 or so minutes to ask clarifying questions and make sure they understand the problem. Then there's another 5 or so minutes of them thinking through the problem and coming up with a solution that they can code.

Ideally, the candidate should be able to write the code for the solution in around 10 minutes. That's 30 seconds per line at 20 lines of code. If your problem requires more than 20 lines of code to solve, you're going to miss out on talking through their code with them. You'll also miss out on being able to scale your question to see how adaptable their code is to change.

The Problem Is Niche And Took You More Than An Hour To Solve

It's very rare that your problem space is so niche that you only want a candidate that has an EXACT set of knowledge in your problem domain. More likely, it's the case that you want to determine if the person knows her/his fundamentals well enough to be able to quickly adapt and learn a new problem space. Because of that, you should avoid niche questions or questions that require you to have super in depth knowledge about the problem space.

A better way to determine if the person is able to adapt and learn is to give them a problem to solve that requires them to critically think through an issue. Once they've satisfactorily solved that problem, change the parameters. You can do this by asking things like "how could you do this with less hosts" or "how could you solve the problem with half the memory usage" or something else that changes an external factor, an input, or an output.

Responding to change is what we do day in and day out as Software Engineers. It's more important to see how well they know their fundamentals and respond to change than it is to determine how deeply they already know your problem space.

The Problem Has Nothing To Do With The Problem Space The Job Is For

Unfortunately, too many times I've seen people ask questions that were not anywhere near the problem space that the job was in. I've seen front end web or mobile developers struggle trying to solve binary tree or problems involving Dijkstra's algorithm when the real problem domain is working with object life-cycle, state management, hardware constraints, and etc.

Make sure that your interview questions are able to tease out whether they will be able to be successful in your problem space. Not whether they know some arbitrary algorithm that isn't applicable or won't help them be successful in your problem space.

The Problem Determines How Clever They Are, Not What Their Skill-set Is

Trick questions, riddles, and brain teasers are not good interview questions. They help determine how clever a person is but not how likely that person is to succeed in your position. There was a time in the early 2000's when you couldn't attend a software development interview loop without being asked a question like "why is a man hole round" or some other riddle.

As an interviewer you want to determine if the person knows the fundamentals of software engineering, can think critically, can adapt to change, and fits in with the culture of your company or team. Your goal is NOT to determine of the person is clever.

Monday, June 27, 2016

In my last post I talked about how to manage your own career as a software engineer. In this post I want to talk about managing someone else's career. As a manager you have a responsibility to your directs to make sure they're aware of what it takes to get to the next level, that they're on the right path, and that they've got the right opportunities to achieve their goals.

Here are some tips to managing someone else's career in software engineering.

Understand their career development goals

Don't make the assumption that what you think they're good at is something that they want to be doing. I've had engineers that would make tremendous project managers or software development managers that just didn't want to pursue those roles. While they were good at them, it was wasn't something that they were passionate about. One of your jobs as a manager is to find out and explore what they're passionate about.

Some of your engineers may not know what their goals are. In this case you should be able to walk them through what options they have available. Help them understand not just how they can advance in their current role, but what other roles are available to them.

Identify their strengths

As a manager you should be able to discern your direct reports strengths. This is does not mean identifying just what they are great at, but also what they would be great at if they just had some coaching. As a manager you need to understand that your directs have both realized and unrealized strengths. Your goal should be to help them realize the ones that they have not already.

Identify the gaps and set some goals

This is probably the most obvious job of a manager but it's also the most over indexed one and one that is often misunderstood. At the core of this problem is helping your directs be aware of the areas that they need to improve on. This will involve having a tough conversation with them about things they're not doing well. When you have this conversation you should be prepared to help them formulate a plan to overcome these deficiencies.

Not all gaps are worth closing. There are some weaknesses that your directs may have that aren't going to be worth the investment from them to fix. Either because it's not going to help them on their desired career path or because the level of investment wont produce enough return to make it worth it. It's as important that a manager helps their directs avoid taking on the work that doesn't play to their strengths as it is to help them take on work that does.

After you've identified the gaps you should set goals to help them gain the skills they need. The key to them achieving their goals is having the right opportunities. As a manager one of your responsibilities is to identify the right opportunities for them and give them a chance to take these opportunities.

Get them visibility

It's important to make sure that as your direct reports achieve their goals that you get them the right level of visibility into their achievements. Getting them visibility helps them gain the trust of other leaders in their space. This in turn will help them get bigger and better opportunities.

Solicit feedback

Part of helping your direct reports grow is getting them good feedback from their peers as well as other leaders in their space. In the course of their day to day they may not have the time or opportunities to debrief on the things they have completed. As a manager you should be periodically checking in and helping them to get this very valuable feedback.

Be able to articulate their achievements

The last key to managing someone else's career is being able to articulate their achievements. This is key because you're likely to have to be their proxy at some point and your ability to articulate their achievement is paramount to their success. At a minimum you should understand:

Monday, June 20, 2016

One of the things I wish I had done better as a Software Engineer was manage my career. I was in the role of software engineer for over a decade but it wasn't until the last 5 years of that portion of my career that I started to take control. For the first 6 or 7 years of my career I naively believed that if I just did a great job my career would advance. I trusted that my management team and senior leaders would recognize my achievements and I would make my way up the leadership ladder.

While there's nothing wrong with having that much trust in your leadership team, in my opinion, it isn't the right way to manage your career because you have very little ownership of your success or failure. You're career should be a reflection of your capabilities and your desire to succeed. Not everyone wants to move up and not everyone is capable of moving up, but most are.

Here are some tips to help you understand how to navigate your software development career.

Start the conversation with your manager

No matter how good your manager is, you have to assume that he or she is unaware of your desire to make it to the next level. Starting the conversation with your manager helps them understand that you want to grow as an engineer.

One important thing to be aware of is that when you have that conversation you're going to need to be prepared to hear about both the good and the bad about where you're currently at. You need to approach that conversation objectively and with a desire to close the gaps. Getting to the next level in your career is mostly about closing the gaps between where you're at and where a person at the next level already is.

Understand the responsibilities

No one is ready to move on to the next level until they're already over performing at their current level and have begun to perform the duties and responsibilities of the next level. Because of that, understanding the responsibilities of your current level and that of the next level is key to growing and achieving your goals. In particular you should understand:

What the expected technical capabilities should be

What the volume of code that you should be producing is

What the expected level of autonomy is

What the scope of influence should be. I.e. what influence you should have on your team, across teams, and within your org

What your role should be with respect to your roadmap and the teams day to day activities

Create an achievements doc

If you're anything like me you're not going to remember the important details about your everyday achievements. What I like to do is to keep an achievements doc where I can keep track of the details of my achievements. I don't write in it everyday but I try to re-visit it once a week and make sure that I put my big achievement of the week into it. I like to keep track of what I deliver, who I influenced, and other big decisions I made or contributed to.

I try to keep track of the following information for each achievement:

What the problem was

What the proposed solution was

What the alternatives were i.e. what were the trade-offs

Why the solution chosen was the correct one

What the impact the solution had on the business, the team, operations, and/or efficiency

That last point is important. You're going to need a way to measure each of your achievements. Having data to back up what you do is the best way to have an objective conversation with your management.

Expand your influence

One thing common to every role is that the more senior you get the more influence you should be having. As a junior engineer you're sphere of influence is largely limited to yourself and your work. As you grow and develop you're sphere of influence expands from just yourself to your team. The more senior engineer you become your influence expands outside of just your team to your org. Expanding your influence means identifying what the sphere of influence should be at your current level and what it should be at the next level.

Get a mentor

As a growing engineer you need an outside influence. You need an objective voice to help you see both your strengths and your weaknesses. A mentor is someone that can help you see the obstacles to your career growth. They can help you grow your existing skills and identify new skills that you need to gain.

Create goals

The last step in career advancement is to create a set of goals. These goals should represent a mix of things it takes to be successful in your current role as well as things it takes to show that you're already working at the next level. Your goals should be SMART (specific, measurable, achievable, relevant, and time bound) and should be something that you review directly with your manager periodically (at least once a quarter). Goals are your best way to make sure you're on track for career advancement.

Monday, June 13, 2016

Does your team have an identity? Something that defines them? Something that they can rally around when things get tough? Something that allows them to put a stake in the ground and affect change? Having a team identity provides many benefits that will make your directs happier at their jobs, more productive, and more efficient in their interactions.

Resiliency to change

Identity at it's simplest form means there's a sense of oneness or sameness. For example, my body is constantly changing. The cells I have today, the blood flowing through my veins, and the hair on my head is not the same as it was 10 years ago. But I am still me. When a team has an identity, they are able to be more resilient to change. People can come and go on the team without affecting the team as a whole. Team charters can change without causing a panic. Team identity is the glue that holds things together.

Stability when the crap hits the fan

When a team has identity they have the ability to weather a storm. They have the ability to lean on each other and be honest about mistakes because there's a shared value system. Teams that have an identity tend to help each other out when someone is struggling. Sometimes that takes the tough form of helping someone recognize they don't fit in with the team identity. But more often, it gives people a way to rally around their peers and help them be better.

Allows for a sense of ownership

When a team has an identity the members on the team feel a sense of ownership in keeping the identity in tack. People want to be involved, want to be included and want to be associated with positive results. A team with identity is more likely to have folks who are willing to step up and own the hard problems because "that what this team does."

Gives you a frame of reference from which to engage

When your team has an identity and things happen that are out of character, you have an easy way to engage and address the problem. You won't be fighting an uphill battle just trying to convince people that a problem exists. People will recognize that "this isn't us" or "this isn't how we do things" or "we don't make these kinds of mistakes". You'll be able to focus on working towards a solution much easier.

Monday, June 6, 2016

I don't do PSA type posts often but today's post is a break from more in-depth subject matter. I was reminded recently that I need to say thank you more often to the people in my life. No one said this to me or called this out. But I was having a conversation with someone that was clearly exhausted from busting their butt and when I said I appreciated their hard work (and meant it) their face lit up. It was almost as though a weight was lifted off their shoulders. Their exhaustion seemed to matter and make a difference. That was all the reminder I needed. I was reminded how important it is to just stop and tell someone that you appreciate them.

How many times have you busted your butt to finish a project on time, help out a co-worker, or generally do something awesome or thankless for your team only to have the act go unrecognized? In my opinion, this is a big problem in the technology industry, but one that doesn't need to exist. This is especially important if you're a manager of individual contributors.

All too often we have very packed roadmaps and very busy schedules. As an industry it's not uncommon for us to be queueing up the next big thing before we even have the current thing we're working on out the door. This is great from a delivery perspective and can be helpful in providing a sense of urgency. But what often gets lost in the transition is taking a moment (and I really mean just a moment) to recognize the hard work of those around you.

As managers in the tech industry we often make the mistake of believing that as long as our employees are well paid that they're happy. But a well paid employee who isn't getting recognized isn't getting fully compensated. They're lacking the ability to feel like they matter. A simple thank you goes a long way in making someone feel like a valued member of the team.

Saying thank you can come in many forms. The most obvious is verbal public recognition. But it can also be a small note in an email. Or bringing donuts for your teams daily scrum or planning meeting.

The end of a project isn't the only time to say thanks. You should be saying thank you when you see something that you appreciate. Saying thank for the small things also lets people know you're paying attention. This could be noticing someone be extra helpful in helping a co-worker to solve a problem. It could be for someone doing a better job than you in communicating to the team. It can be someone who's just always on top of things and doesn't let them drop on the floor.

My advice to you is to take the opportunity to stop for 1 minute and thank the people on your team that are busting their butts each and every day to make the team successful.

Monday, May 30, 2016

In most software projects that I have been involved in there's always come at least one time during the course of the project where we've hit a crossroads and the right next step isn't clear. Usually there are two or three competing paths that each have merit on their own.

In these situations its typical for people to start relying upon conjecture. The conversation starts to turn from we should to I think. What's the problem with I think? It means:

The data the decision is being made on is coming from you and not your users.

The conversation starts becoming more subjective and less objective.

There is more risk that you build the wrong thing.

In many situations our experience is going to be enough to make a decision with incomplete information. But you need to be aware when the cost of making decisions based on conjecture can affect the success of the project itself. When there's a lack of data about something that affects the direction of the software using the term I think should be a red flag. Here are three key questions you should ask before proceeding:

If I make the wrong decision, am I able to go back and change it?

If you're building software that others are building on top of then it's likely that their business now relies on the decision you've made. In this case once you've released the software it's going to cost a lot of money and time to go back and change it. If you have a large user base it's even likely that some users will be unwilling to change their use.

What's the cost associated with the decision?

Does your decision require you to make significant purchases in hardware or other software? Do you have to bring on additional people on to the project to complete it? How much additional time will be spent building the proposed solution?

If I build this solution, what am I not able to build?

It's possible that deciding to do X means that you cannot do Y or Z. It's important to understand these trade-offs before you start down a particular path.

So how do you turn the conversation from I think back to a confident we should? Answering those three questions is a good start. But you need to also start the conversation with your users. In agile the product owner is the proxy between you and your users. Product owners are usually in touch with the actual users and can provide a more objective opinion on what your users will really need or want. Bring your product owners up to speed on the context and the ramifications of the decision. Let them help you get the right data to minimize your risk of building the wrong thing.

Monday, May 23, 2016

How many times have you been working on a platform and recognized the need for some underlying technology that ties together several disparate components in your system. The conversation usually goes something like this.

We've been building component A for some time and we need to build component B and C. A's been doing well but has a lot of warts and tech debt that we'd like to fix. If we only had a generic system X then we could build B and C faster and reduce redundancy between A, B, and C.

On the surface that reasoning seems sound. You're not dreaming up an ideal system and looking for problems it can solve. You have real world problems you're trying to solve for components A, B, and C. So what's wrong with setting out to build a generic system to solve your problems?

You aren't providing business value along the way

By building a new generic system instead of refactoring your existing system you're increasing you're opportunity loss costs. Every day that you spend building software that doesn't get into customers hands is a day of missed opportunity for feedback. You aren't able to get feedback on whether your solution actually fits the customer need. You aren't able to get feedback on what the unknowns in your system are that only come out in production. You aren't able to get feedback to validate the many assumptions you've had to make along the way. Building successful software requires a closed feedback loop between you and your customers. The longer you go without closing that loop the more risk you are adding that you're building the wrong thing.

Generic systems come with too many unknowns

A generic system needs to be able to solve problems it doesn't even know about. But often, these aren't problems that you have today or will likely have in the near future. Building your system in such a way that it can be delivered in small pieces that provide immediate business value allows you to make sure you're solving the correct problems today, and building a foundation that can be refactored and abstracted tomorrow to solve different problems that are unknown today.

It's easier to do the wrong thing than it is to do the right thing

When building a system for which you don't know the full requirements it's easier to do the wrong thing than it is the correct thing. That's because you're possibilities are almost infinite on what you could build, and at best you just have a educated guess as to what you will need to build in the future. This means that you're going to have to make assumptions that can't be validated. It's very possible that you make design decisions based on these assumptions that are difficult to go back and change. Building only the components you need today ensures that your system only needs to change for the problems you have, not the ones you think you're going to have.

Refactoring existing systems allows you to get the more generic solution that you need

As you build the systems and components you need, you'll be able to start identifying the parts of your system that are needed across components. These common components are the real foundation of the more generic solution you need. Building them to solve your specific problems today means that they will only do what they need to do (i.e. you won't have spent time building features that aren't used). This will create a virtuous cycle of refactoring and adding more functionality as you need it. You'll get the correct level of abstraction for your components because you'll only be abstracting them when you have a real world need for the abstraction.

Monday, May 16, 2016

It's unfortunate how much software gets written and never actually ships and is used. This can't be wholly avoided because there are times when priorities do change. There are times when projects do need to get shelved due to more pressing needs. And if you're working at a company that values risk taking then projects will get canceled in an effort to fail fast.

As a software engineer not shipping due to changing priorities or having to shelve something in favor of a more pressing project were two of the most demoralizing things. Especially when I had worked on a project for N weeks or (even worse) N months.

Being able to ship software fast is one of the big benefits of Agile software development. Agile encourages you to ship at the end of every sprint. In the ideal world this would mean putting something in users hands that can be used at the end of every sprint. In reality, this is usually not the case. Often, you ship a series of smaller end-to-end pieces into production which at some point you'll tell your users about.

Here are some things to consider which will increase your likelihood of shipping software your users will use and decrease the chance that you'll build the wrong thing.

Understand your problem

While this sounds like a no-brainer, it's actually one of the things that I see get missed the most. Understanding your problem is not about requirements gathering. You gather requirements about a known problem space. One reason software projects can fail and never ship is because the problem was based on an idea that was never validated. You should always be able to tie your problem back to something a user has asked for.

Identify your milestones

Many software teams identify milestones from the beginning and move forward linearly in time till shipping. This is not a pit of success in that it's easier to miss a requirement than it is to not miss one. It's better to start with the last milestone and ask the question "what needs to happen right before this to achieve this milestone". Then you keeping going backwards in time asking that question and defining new milestones. Eventually you'll get to a requirements gathering milestone. You'll have achieved either defining all your milestones, or identifying ambiguity that would have likely derailed or delayed your project had you started defining milestones the other way around.

Know your risks and how they can be mitigated

Every project comes with risk. Being able to identify what risks are associated with your project will help you determine how your project will succeed in the event that one or more of your risks are realized. Some common risks to software projects include:

Upstream/downstream software dependencies (often internal software being developed by another team) being late or failing to ship all together.

Hardware/software purchases that need to be made.

Making sure you're able to deploy to production.

Not having user documentation.

Not having a marketing plan for a new feature or product.

Getting started with performance testing or security reviews late (or not realizing you need to do them at all).

Make sure you know what you need to measure

Milestones are great to help you know whether your project is on track. But they won't help you once your software is released. You need to identify the ways that you should measure your software to understand it's health. You should understand both your customer facing metrics (like the number of failures, the latency of requests, or etc) as well as your internal metrics (cost, performance, system health, etc). Talk to your product owners and your sales teams to understand what they need to measure about the software in order to aid them in their jobs.

Have an exit criteria for success

What is your definition of done? This doesn't mean you won't maintain or make changes. It just means that you've successfully delivered what you wanted to deliver. This should be a checklist of items that's been validated on both the business and technical sides of the house.

Monday, May 9, 2016

In my previous post, writing code that will last: understanding bottlenecks, I talked about how bottlenecks can come in the form of vertical scalability, horizontal scalability, or statefulness. In this post I'll explore how identifying upstream and downstream dependencies in your software can make or break it from a longevity perspective.

Upstream Dependencies

There are several upstream dependencies that you need to consider in your code. These come in the form of your operating system, the platform your application or service runs on, the external applications and services you use, and the contracts you depend on for data.

Operating systems and software platforms can affect the performance, security, and ability of your service. Writing code that lasts means abstracting your code enough from the OS and underlying platform such that you can upgrade the OS or platform without changes to your application or service. This allows you to protect your self and your customers from security vulnerabilities as well as allows you to take advantage of performance enhancements that come from kernel or library updates.

You should also consider the dependencies you have an external applications or services. Do you depend on them in a version specific way? How will your application need to change if they change the schema of the contract you have or deprecate an API you use. Building code that will last doesn't mean prematurely optimizing your code to try to defend against these changes, but instead means understanding how to encapsulate them such that the effect these changes have on your code are minimal.

Downstream Dependencies

Downstream dependencies are people, applications, and services that depend on your software. From a downstream dependency perspective writing code that will last means understanding when you're making a choice that you can't go back and change after the fact. In order to write code that lasts we have to minimize the number of these choices that we make. These choices often come in the form of the APIs we expose, the contracts we create with other services, the way we represent objects, and etc. Once these choices are made, sometimes they can't be taken back without having some sort of negative side effect.

Monday, May 2, 2016

In my previous post, writing code that will last: avoiding potential roadblocks, I talked about how roadblocks can come in the form of cost, re-inventing the wheel, or under-defined requirements. In this post I'll explore how understanding potential bottlenecks in your software can make or break it from a longevity perspective.

Understanding Bottlenecks

The first bottleneck you should be considering is how your application scales vertically. Vertical scale typically has direct correlation with your applications performance characteristics. Vertical scale is achieved by increasing CPU, Memory, Network Capacity, or Disk your application has available to it. Is your application going to be CPU or Memory bound? Will you require a lot of Disk I/O? How much data will you be reading/writing over the network? You need to understand each of these areas in order to know how your application will scale vertically.

How your application scales horizontally is the next potential bottleneck you should understand. Horizontal scaling is the ability to add additional machines running your software into an existing pool to add additional computing. Horizontal scaling allows you to increasing the throughput of your application by having more capacity to process requests or jobs that the application performs. Your software needs to take this into account from the beginning or it won't last without requiring rework.

Another area to consider when understanding your applications bottlenecks is how stateful it is. Does your application require some external state in order to run? How the application gets and maintains this state can lead to potential bottlenecks. E.g maybe your application needs some specific information about the user making the request that it has to lookup somewhere. Or maybe it needs information about previous requests. An example of a stateful application is one that uses a shared database. The reason state cases bottlenecks is because your application is now dependent on something external that it does not control.

Monday, April 25, 2016

I've written about writing code that will last before from the context of coding standards. Today I'd like to look at it from the non-code perspective.

As a software engineer one of the best feelings was wrapping up a complex solution and feeling like I had written beautiful code. Code that sailed through peer review unscathed. Code that adhere'd to the standards of my team. Code that used best practices. Code that was simple and elegant.

One of the worst feelings as as software engineer was realizing that your beautiful code wasn't standing the test of time. Maybe it wasn't flexible enough to adapt to changing business requirements. Or possibly it created an unnecessary bottleneck. Or, despite the peer reviews, it wasn't as performant as expected.

Writing code that will last is about being able to look around corners and see the non obvious. Aside from the obvious, writing SOLID code, it's about avoiding potential roadblocks, about understanding bottlenecks, and identifying upstream and downstream dependencies. In this post I'll explore avoiding potential roadblocks.

Avoiding Potential Roadblocks

One of the biggest roadblocks to software engineering is cost. Cost can come in many different forms; cost of development, cost of maintenance, cost of infrastructure. There are two areas to think about when considering the cost of software. First is ROI (return on investment). Does putting the software into production and keeping it in production save or make you more money in the long run than it will cost you to build and maintain? Make sure you're considering the operational overhead when determining ROI.

The second are to consider with regards to cost is opportunity loss costs, i.e. what software are you NOT building so that you can build this software. Your team could be building many different things. Why is this project the right one to build now? Is there something else you could be building that gets you a competitive advantage, a higher ROI, or reduces operational overhead?

Another roadblock to long lasting software is re-inventing the wheel. At it's simplest form it means writing software that already exists. It could exist as open source software, COTS (commercial off the shelf) software, or some internal library in your company's software portfolio. The latter is more often the case at larger companies as is having two different teams writing similar code at the same time. Sometimes in order to not re-invent the wheel, you need to change how you're approaching solving your problem so that you can re-use existing software.

The last major roadblock to avoid is under-defined requirements. There's nothing worse than building a solution and realizing you it doesn't solve your problem because it didn't uncover the need for feature X. This is especially demoralizing to the team if they've just spent months building the software. The easiest way to avoid this is to have very clearly defined user scenarios up front coupled with short end to end milestones that allow you to get your software into production quickly. This allows you to reduce your feedback loop time and adapt to changing or unrecognized requirements.

Monday, April 18, 2016

One thing that I always struggled with as a software engineer was reconciling what I knew about myself and what other thought about me. Every year during annual reviews (more often with the good managers) I'd get a glimpse into how others viewed me in the form of my performance review. I was not usually surprised with my overall performance rating, but there were usually things that came up that I wasn't aware others were paying attention to. Some good and some bad.

As I've shifted into a management role I've come to really appreciate how much your reputation can help you succeed or get in the way of your success. One of the things I try to work with my engineers on in making sure that the best of themselves comes out in how others view them. It's just easier to succeed in your role and in your career growth if others have an accurate view of your skills and capabilities, and if you're open to the areas you need to grow in.

All too often I see engineers trying to change their reputation by telling others that they're not what they seem to be or making excuses for why they act a certain way. More often than not, this is not helpful. Instead you need to be doing something different to change your reputation. Here's some tips to successfully manage your reputation:

1. Decide that you care about your career and your own personal growth

Almost everyone I've ever managed or lead on a team has said that they care about their career and their own personal growth, but when confronted with challenges many have decided that overcoming those challenges required more work then they were willing to do. They give up and let their reputations dictate their opportunities and their success or failure.

The biggest hurdle I've experienced to making this decision is believing that you can be successful. You have to know that the road ahead is difficult, that you are capable of success and then make a conscious choice to put in the effort to grow.

2. Understand what your reputation actually is

The first key to this is just preparing yourself that you're going to hear things you don't want to about yourself. You're going to hear that you struggle in areas that you either don't believe matter or that you don't believe you struggle in.

The unfortunate reality is that if you're hearing feedback that you don't believe to be true, there is something you're doing (or not doing) that is contributing to the reputation. This is not to say it's your fault. But you must acknowledge that you have room to grow.

Personally, I've heard my whole life (not just in my career) that I'm too combative. I see that trait as being passionate about what I believe. While that may be true (at least I hope) it doesn't change the reality that I am viewed through that lens and that I can't change that view until I actually understand that it is a filter that people are using when interacting with me.

3. Look for ways to capitalize on your strengths

One mistake I made at the beginning of my career was using a strength ineffectively. I'm a person that has always had good intuition and perception. I pay attention to little details and become aware of things that others don't recognize. The mistake I made with this was two fold. First, I thought that because my intuition and perception were very good that they were flawless. In other words I thought I was always right. Second, I thought this good intuition was a license to offer advice even when my advice wasn't sought out. These two mistakes compound and ended up building a reputation of being a know it all.

Through very successful coaching by managers who recognized this strength being used ineffectually I've learned to turn something that was making me ineffective into something that makes me more effective by asking questions. When I intuit or perceive something that I don't believe others are seeing I now ask questions instead of making statements.

This helps me in three ways. First it shows that I'm open to being wrong about my intuition or perception. If I'm open to being wrong and others are aware of it, they're more open to me being right. Sounds odd but it's true. What I'm doing is creating a culture where failure is okay and others don't feel like I'm judging them if I succeed or if they fail. Second, it helps others to feel like they're also apart of the solution. By asking a question you're inviting them to participate. By helping others to be involved they feel ownership in the result. Lastly, it helps me uncover the things that I don't know I don't know. Occasionally, these questions will uncover evidence to reinforce my initial intuition or perception. But more often they will uncover things I wasn't aware of that help me gain a more solid understanding of what we're talking about.

The key here isn't just to make sure you have opportunities to showcase your strengths, it's to learn to make your strengths more effective.

4. Look for opportunities that allow you to growth in areas of weakness in a way that sets you up for success

Everyone has room for growth. Effectively managing your reputation with respect to these areas of growth means learning the skills necessary to be effective and then practicing those skills. Once you start to master these new skills you then look for opportunities to scale them.

One common example I run into is growing as a leader. Most ineffective leaders, in my experience, think leading is about directing others so they focus on being right and setting the direction (read: telling people what to do). The result is that these people get a reputation as micro-managers who don't trust their direct reports or peers.

An example of growing in this area is by learning what motivates people and then learning to apply that motivation to what needs to be done. This results in leading by getting people to want to do the right thing.

Monday, April 11, 2016

One mistake I've often seen made when planning for a software project or planning the road-map for a team is not taking into account the total cost of development. We often fall into the trap of planning our software based on one key data point; development effort. While development effort is likely the most volatile variable that goes into the cost of a project, it is by no means the only variable.

Planning isn't free

There are three major areas of planning that need to be accounted for when considering the true cost of a project. The first is in defining what the customer needs. This will involved someone (or multiple people) being the advocate for the customer. Likely this will involve a certain amount of research and a certain amount of customer interaction.

The second is in identifying upstream and downstream dependencies. Before you introduce change into your system, you need to understand how that change will affect people that depend on your system and on the systems you depend on. For instance, will your changes cause you to put more load on another system? Will they cause you to be able to handle less or more load on your existing system? Do they require your existing consumers to do additional work or is there work they can stop doing? It is likely that you will have to make some change in your system to account for these dependencies.

The last area is in defining key performance indicators. These are metrics that allow you to know if your software is working correctly or not. If you don't account for defining these then you won't be able to truly measure whether or not your software is successful.

System Architecture (or high level designs) aren't free

Often we think about a project start as the time when the developers start writing code. But this is incorrect. The old adage "measure twice and cut once" applies to software development as well. To build the right system, one that works for your customers, you need to have a solid design. True software costing accounts for the design and the time it takes to review the design.

Development

I don't think I need to state the obvious, but I will for completeness. You need to account for the actual development effort in the total cost. Usually this is done in dev weeks. This could be one dev for 12 weeks or 3 devs for 4 weeks, depending on the parallelization that the project allows for.

Bug Fixes and Stabilization aren't free

Before you put any code into production you should be testing that code in a production like environment. Many teams have an integration or pre-prod environment which is built as a smaller scale replica of production. The very best teams have a way to drive production like traffic in this environment to help root out the bugs that seem to only be able to be found in production (like race conditions, threading issues, memory or other problems of scale).

Deploying Software isn't free

Hopefully by now your organization has started to, if not fully, embraced the DevOps movement. Irregardless of whether you have full continuous integration setup or a fully manual deployment there is some cost associated with the deployment of your code. In a fully automated environment it may be the cost of updating the automation. In a more manual deployment scenario it'll be the cost of validating and pushing the bits to production.

Maintenance and Operations isn't free

Once your software is in production, you have an implicit contract with your customers (if not explicit) to make sure that software is running. This involves routine maintenance as well as the operational cost associated with keeping the system running smoothly and responding well to changing usage patterns. Inevitably hardware fails, systems get more load than we expect, and bugs exist in the system that require intervention. Accounting for this cost is crucial in understanding the total cost of software development.

Documentation doesn't write itself

The last area that I want to call out is documentation. This is often forgotten about until it's too late. Your code should be as close to self documenting as possible, but your users will need a guide to the feature or the product. Don't forget to account for this in your costing.

Monday, April 4, 2016

Prior to purchasing my Pebble Time I hadn't worn a watch in almost a decade. I stopped wearing a watch after breaking several in day to day activities. While it was less convenient to look at my phone for the time, it was better then shelling out hundreds for a new watch every couple of years.

The Pebble Time was the first smart watch that actually made me want to wear a watch again. Not because it was a great fashion accessory, but because I hoped it would fill a couple gaps of convenience for me. I really liked the idea of being able to respond to text messages via voice, being able to see my calendar and get reminders without having to pull out my phone, and being able to do a variety of small tasks like checking the arrival of the next bus.

The input problem

Reading messages, calendars, activity tracking, and other types of small time bound information like sports scores and bus schedules is pretty easy and convenient on a smart watch. But inputting information is incredibly difficult. There are three main ways to input information and all three of them suck. There's canned phrases, voice dictation, and keyboard input.

Given the small size of the smartwatch input, the only effective keyboards I've seen are T9 style. Anyone who remembers features phones remembers what it's like sending a text on a T9 keyboard. It's difficult and time consuming. A full keyboard on a smart watch is likely a non-starter unless someone can figure out how to make Swype like functionality useful on such a small screen. The only way I can see a keyboard being useful on a smartwatch is for it to learn how I talk and to predict what I'm going to say.

Voice dictation on a smartwatch isn't everything I thought it would be. There are times when it's incredibly useful but more often than not, it's just not convenient to dictate via voice. It's super frustrating when you dictate a long sentence and it gets 99% of what you said but changes some crucial word or phrase such that the entire dictation is meaningless. This happens often enough to make me not trust that it's going to be correct. Another problem with voice dictation is that often your surroundings aren't conducive to you being able to dictate via voice. A good example is when standing in line at the coffee shop or riding on an elevator. Speaking into your wrist in these situations just feels awkward. Whatever I'm trying to do, whether it's set a reminder or send a text message, the conversation feels too intimate for me to be saying out loud. It's also just weird to be talking into your wrist and not to another person.

This leaves canned phrases. I don't know about you but I can't seem to narrow down all the things I'm going to need to say at some point in the future to 4-5 canned phrases. It would be useful if the watch could predict what I wanted to say based on previous conversations. interactions, or time of day. For example, everyday when I'm leaving work (between 5-6:30pm) I send my wife a text saying I'm packing up. The likelihood of that being what I want to send in that time-frame Mon-Fri is pretty high. It would be nice if my watch allowed me, with one click, to send that message. For everything else, I've found that what I want to say is so context specific that canned phrases just aren't useful. The only thing I can think of that may work would be if the companion phone app was monitoring everything I sent and building a profile and creating dynamic canned phrases. But, that's just creepy.

The battery problem

The battery life on the Pebble Time is really good. I only have to charge my watch once a week. But even that feel too often. I couldn't imagine what it's like to own an Android or Apple watch where you have to charge it everyday. Smart watches need to perfect wireless charging. I'd be more than happy to have a wireless charger setup at my desk at work and near my couch at home. I'm in both these locations often enough that my watch should be able to keep a charge indefinitely. I should not have to think about taking off my watch and charging it.

Monday, March 28, 2016

Over the last decade or so I've worked on a lot of teams chartered with building APIs, web services, and/or micro-services that were consumed by external and internal software. When building something that's composed into another system you're inevitably going to have to make design decisions which, if used incorrectly, will not have the desired effect on the system.

A few years ago a former co-worker of mine introduced me to a concept that helped change how I approach solving for this problem. That concept was called the Pit of Success. In it's most basic form the pit of success can be defined as follows:

Pit of Success: being easier to do the correct thing than it is to do the incorrect thing?

So how do we create a pit of success with the products we build? Here's some simple tips.

Solve for the 80% case out of the box

By default the software should solve for the 80% use case. Often this can be accomplished by simply creating reasonable defaults for configurable parameters. The way I like to solve for this is by asking myself the question "what is the out of the box behavior?"

Make the developer do work to harm the system

Most of what we do on the web involves creating, updating, or deleting data. Occasionally we have to build things into a system that can have harmful if used incorrectly. In these particular cases you can create a Pit of Success by making the developer do work to enable the potentially harmful feature or use the potentially harmful API.

Familiarity

Be conscious of the platforms and frameworks that you're working with. Don't invent new conventions that don't add material value to the system. Use idioms and patterns that are natural to the developers of that platform.

About Me

I’ve been in the technology industry for 14+ years mostly as a Software Developer. I've worked on projects ranging from a Ruby on Rails Portal, a high performance/low latency .NET search stack, R&D for building infrastructure in the cloud including automated server builds using Chef, to architecting and building iOS and Android Mobile platforms and frameworks.I've also spent some time building Android, iOS, Windows Phone, and Bada mobile applications that focused on the presentation of long form audio/video.The middle of my career was spent at MSNBC working on their content management publishing platform, their video syndication system, as well as being a co-creator of their iOS iPad framework from which the Rachel Maddow, Today Show, and Nightly News iPad apps were built.Finally, the beginning of my career was spent writing software on government contracts with a few years spent writing criminal investigation software.