Being mediocre before being great

Do you have an ambition to be a top performer in your job? Do you have a hero who you want to be like when you grow up?

I have an ambition to be a top performer in my job. I have a picture in my mind of what success will look like, gleaned from reading and looking at leaders around me. Someday, I say to myself, I’ll be able to provide trusted advice on technical direction that improves the productivity of an entire department. Someday, I’ll be able to deliver a talks or write blog posts about my work that inspire and motivate others, and provide value to their careers. This is a vision of greatness.

However, before I can be great, I must be mediocre. The thing about picturing great success is it doesn’t tell me how to get there. I need to break down an ambitious and, to be honest, at times overwhelming, goal into manageable steps. I need to build the discipline to get stuff done. I need to be okay with failure and mistakes.

I’ve already taken some career steps:

  • I used my performance review as an opportunity to ask for a raise in writing. After listening to Kalzumeus Podcast Episode 12: Salary Negotiation with Josh Doody, I realize there are a few things I can do better next time, but it was a good first step.
  • I participated in my first story mapping/story authoring session. This is an agile practice for gathering user requirements in the form of a flow-chart-like diagram.
  • I started sending weekly updates to my boss. These detail my progress on company objectives and the general sprint work. See: Selling Yourself: How by John Sonmez.

By themselves, these steps don’t turn me into a software developer guru, but they are a step in that direction.

Another post on being senior

Last week I wrote about how senior developers take the initiative instead of waiting to be told what to do and how to do it.

Sarah Mei had a great series of tweets on the differences between junior developers, mid-level developers, and senior developers.

  • Junior developers need help figuring out how to do things. They don’t have the research skills to get things done on their own.
  • Mid-level devs have figured out the how and are starting to get the why, though they don’t communicate their ideas very well.
  • Senior devs long since figured out the how and the why. They have their own ideas and can get other people to go along with their ideas.
  • There’s a limit to how much impact one person writing code has. Senior-level impact is when you can change how other people write their code.

Tweets: 1, 2, 3, 4 (edited slightly since I don’t have a 140 character limit and I can add formatting)

I’m going to piggyback off what Sarah Mei wrote and add my own two cents.

First, the how. How is the basic mechanics of getting your job done. Say you need to fix a locale bug. The how is figuring out which source code is causing the behavior, and finding the file and line of code to modify. It’s also reading the docs to understand how locale is supposed to work.

Sometimes you get stuck. For example, you realize that in Electron, the renderer processes have access to navigator.language, but the main process does not. How will you make sure that the main process gets the correct locale?

I heard a rule of thumb that you shouldn’t let yourself be stuck in the how for more than 15 minutes. If you get stuck too long, you should ask for help. This is where the rules for asking questions can be helpful: provide context to what you’re trying to do, explain what things you tried, and show a concrete example. Eric Raymond has a great document “How to Ask Questions The Smart Way,” of which I would point to the “Be precise and informative about your problem” section.

As you grow your expertise, you won’t get stuck as much, or (more likely) when you do get stuck, you can get unstuck after doing a little bit of research on your own.

One time I asked a coworker how Java handles integer overflow. He said, “I don’t know, let’s try something,” and proceeded to write a quick unit test and used the IDE’s debugger to show the result. I felt sheepish because I realized I could have done this experiment on my own.

Programming can be a lot of fun when you can quickly write some code to prove/disprove a theory of how something will work.

Next, the why. I think a good example of this is clean coding. At some point, somebody wrote a bunch of spaghetti code, so now we have a best practice of writing modular code with loose coupling. At some point, somebody wrote the entire system using singletons, but then when it came time to maintain it, it was like dealing with a bunch of global variables, and nobody wants that. Now we know why injection is a common practice for dependency management. A mid-level developer understands clean coding and uses it in their own code, and a senior developer can get other people go along with clean coding practices.

In addition to the why of certain programming practices, there are processes or business decisions that it is helpful to understand the reasoning behind. For example, understanding the product vision. Who is the target audience for a particular feature? Are we trying to expand our product to new customers, or retain existing customers? When you know what lies behind the decisions that are handed down to you, you are able to make sense of the priorities of the business.

Sarah’s point about being senior is that a senior developer understands the why and is able to persuade others. To put it another way, it involves leadership. It’s not enough to have the right idea, you have to be able to motivate others to go along with you. It’s not enough to have the technical skills to write code. If you want to stand out as a senior developer, you need the soft skills to work with others and persuade them.

Taking the initiative

I came across an article by Vaggelis Giannikas about the 3 stages of being a Ph.D. student. Each stage involves taking more initiative and responsibility, and they lend themselves to comparison with what it means to be a mature software developer. Here are the 3 stages, reworded slightly for the non-academic world:

  1. I expect my boss to tell me what to do.
  2. I do my own research on the different options and go to my boss for advice on which one to pursue.
  3. I decide what to do and persuade my boss if s/he has any doubts.

Adapted from: XRDS Vol. 21, No. 3, Spring 2015, “The PH.D. Journey: Tips from somebody who managed to defend his thesis”

Growing as a software developer means moving from stage 1 to stage 2 to stage 3. In each stage, the software developer takes more initiative and also bears more responsibility for the outcome.

For example, in stage 1, a junior developer expects his boss to tell him what bugs to work on, and might throw in a few small features. The junior developer is mostly responsible for asking for more work, and the boss is responsible for reviewing what was done and making sure the right work is being done.

In stage 2, the boss has given a developer a larger feature, and the developer goes and researches 2 different solutions that would implement it. If the options are different technical choices, she might go to an architect for advice. If the options would have different product/user experience implications, she might go to a product manager for advice. The stage 2 developer is more proactive in getting the necessary information to make the decision.

Stage 3 represents someone who is an architect or product manager. They decide what to do and persuade the rest of the organization if they have doubts. Persuade is a great word here because it’s saying I can be a stage 3 developer without actually having the title that goes with that. In other words, even if I’m not a manager on the org chart, I can have that kind of influence on others. The stage 3 developer bases their decisions on their experience and expertise, and is responsible for impacting the organization in a positive way.

In conclusion, I liked this outline of what it means to grow as a Ph.D. student because it can be applied to becoming a mature software developer. As I grow in my ability to write code, I want to grow in my ability of seeking advice, making decisions, and persuading others.

How to make the most of a manager 1—1

The weekly manager one on one (1v1, 1:1, 1—1, choose your own punctuation) is a staple for office workers in contemporary corporate culture. Whether it’s weekly, every other week, or once a month, you’ll meet with your manager and have no idea what to say. At least, I didn’t know what to talk about.

When I started my career I had a few wrong assumptions about the weekly manager meeting. First, I assumed that the manager meeting should only happen when my manager sent me a calendar invitation. I ran into a situation where my weekly meeting suddenly disappeared off my calendar, and I assumed that this was an intentional cancellation. Three weeks later, I finally asked my manager about it, and he apologized for the lapse; he had not renewed the calendar invitation. I learned that if I had spoken up sooner, the problem would have been fixed right away.

Second, I assumed that the meeting had a specific agenda or desired outcome every week. I was a little frustrated about how open ended it was. My manager straightened me out, saying that often the agenda is just “let’s catch up.” I learned that this can still be valuable, just as a way of building a rapport and a relationship with my manager.

More recently I have come to realize that I can control the agenda in these meetings. If I plan ahead a little, I can think about what I want to talk about. There are a few areas that I’ve found valuable to bring up.

Managers are busy. They have other meetings, get hundreds of emails a day, and generally can’t keep track of everything going on around them. I found my manager one on one more valuable when I viewed it as an opportunity to make my manager aware of how I add value. I can help them by talking about the following:

  • Something I did successfully this past week
  • Talk about a time I helped someone with my expertise
  • Talk about how I’m completing my work on time, or if I’m my work is pushing beyond the estimate, why this is the case.
  • Talk about any advice I received, or any decisions I made.

Generating this kind of awareness or visibility can feel like self-promotion. However, I like to think of it as helping my manager be aware of the value I’m adding to the company. From a manager’s point of view, would you rather have to go pester each person and figure out what their doing? Or would you rather have them come to you and proactively give updates on how they’re kicking ass.

Another idea for the weekly manager meeting is to have a conversation. It’s a time slot in my week when I are not expected to be “heads down” coding. Instead of focusing on the quantitative, I can focus on the qualitative. I got this idea from the Hanselminutes episode “Speak up and present with confidence.

In this same vein, it is a chance to make sure I’m on the same page regarding any recent changes to projects I’m are working on. Was there an announcement that impacts my priorities? Did the process change? I can use the weekly meeting as an opportunity to make sure that I understand what is expected of me.

Hopefully these ideas help you like they helped me. Think of it this way: you’ll have that 30 minute time slot on your calendar regardless; why not make the most of it?

Quotable quotes 2

This post got me thinking: the structures that help people learn coding will also help experienced programmers be more productive.

Working in the head doesn’t scale. The head is a hardware platform that hasn’t been updated in millions of years. To enable the programmer to achieve increasingly complex feats of creativity, the environment must get the programmer out of her head, by providing an external imagination where the programmer can always be reacting to a work-in-progress.

Source: “Learnable Programming,” Bret Victor.

Office Politics 101 for Recovering Idealists. The article title says it all. I found this eye opening.

In the meantime, there’s a pretty easy rule of thumb to follow. When in doubt, keep it to yourself. Listen more than you speak and certainly more than you vent, collect as much information as possible, and ponder how it can be used to make yourself seem more of an asset to your boss than your competitors.

Source: “Office Politics 101 for Recovering Idealists”, Erik Dietrich.

I was encouraged to know that a pattern of thinking I sometimes slip into has a name. It also challenges me to overcome this distorted thinking so that I am no longer controlled by fear.

Catastrophizing essentially involves imagining and dwelling on the worst possible outcome of something. It’s basically overreacting and letting your thoughts run away to dire and highly unlikely scenarios. It’s the kind of thing that happens when you’re lying awake at three in the morning worried sick about the future and what’s going to happen to you.

Source: “Building Your Resiliency: Part VI – Quit Catastrophizing,” Brett & Kate McKay.

Patrick McKenzie with one take on a software career track. This article influenced me a lot:

Engineers are hired to create business value, not to program things:  Businesses … converge on doing things which increase revenue or reduce costs.  Status in well-run businesses generally is awarded to people who successfully take credit for doing one of these things.  (That can, but does not necessarily, entail actually doing them.)

Source: “Don’t Call Yourself A Programmer, And Other Career Advice,” Patrick McKenzie.

Quotable quotes

It would be arrogant of me to think that I have solved the problem of large-scale software development:

It is widely acknowledged that coordination of large scale software development is an extremely difficult and persistent problem.

Source: “Splitting the Organization and Integrating the Code: Conway’s Law Revisited,” Herbsleb and Grinter, 1999 (PDF).

One of the most common antipatterns of commercial software development:

In this evil, but extremely common, mirror universe, developers branch to create features. This branch stays isolated for a long time. Meanwhile, other developers are creating other branches. When it comes close to release time, all the branches get merged into trunk.

At this point, with a couple of weeks to go, the entire testing team that has been basically twiddling their thumbs finding the odd bug on trunk suddenly has a whole release worth of integration and system-level bugs to discover, as well as all the feature-level bugs which have not yet been found because nobody bothered to have the testers check the branches properly before they got integrated.

Source: Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation, Humble and Farley, 2010.

This view is too optimistic for me, given what I know about human nature and our sinful condition:

Technological optimists believe that technology makes life better. According to this view, we live longer, have more freedom, enjoy more leisure. Technology enriches us with artifacts, knowledge, and potential. Coupled with capitalism, technology has become this extraordinary tool for human development. At this point, it is central to mankind’s mission. While technology does bring some unintended consequences, innovation itself will see us through.

Source: “The Moral Character of Cryptographic Work,” Rogaway, 2015 (PDF).

This article was how I first came across the work of Erik Dietrich. Since then I’ve had a lot of fun reading his articles on software development and office politics.

In the sense of skills acquisition, one generally realizes arrested development and remains at a static skill level due to one of two reasons: maxing out on aptitude or some kind willingness to cease meaningful improvement. … [L]et’s discard the first possibility (since most professional programmers wouldn’t max out at or before bare minimum competence) and consider an interesting, specific instance of the second: voluntarily ceasing to improve because of a belief that expert status has been reached and thus further improvement is not possible. This opting into indefinite mediocrity is the entry into an oblique phase in skills acquisition that I will call “Expert Beginner.”

Source: “How Developers Stop Learning: Rise of the Expert Beginner,” Erik Dietrich.

Computer security reading list (part 2)

I came across Bruce Schneier’s “CRYPTO-GRAM” many years ago when it was an email-only newsletter, and ever since then I’ve been interested in security. Taking St. Cloud State’s Computing Ethics class (CSCI 332) gave me more connections with how security affects computers.

Continuing my last post, Computer security reading list (part 1), this post includes some resources on computer security. Not that I’ve read everything linked to here, but I’ve read enough to be drawn in and informed. I hope that you may find these useful as well.

Blogs (continued)

  • Google Project Zero Project Zero is a team at Google that looks at different systems and finds and documents zero-day vulnerabilities.

Articles

Lectures

Computer security reading list (part 1)

Blogs

Books

Talks

Reports

Finding concurrency bugs in Objective C

Introduction to concurrency in Objective C

We can introduce concurrency to a process by creating threads. Within a process, threads use the same memory space and the same instruction set. Each thread has its own position within that instruction set. A thread is in one of 3 main states: running, ready, or blocked. Each thread has its own register state and its own call stack.

In OS X 10.6, Apple introduced Grand Central Dispatch, a thread pool technology that simplifies the use of threads. GCD introduces the concept of queues and tasks. A process can have multiple queues, where each queue has one or more blocks. A block is a task for execution on that queue. From a programming languages perspective, a block is a closure (a function plus a binding environment). As a user of the queue API, you simply dispatch blocks on the queue, and GCD manages the running of queues.

Behind the scenes, GCD will create and destroy threads as needed in order to handle the workload of the queues the user has created.

In the case of a serial queue, one block runs at a time. In the case of a concurrent queue, GCD may concurrently execute blocks placed on that queue on different threads.

There are two ways to place a block on a queue.

  • dispatch_sync places a block on a queue and waits until that block completes
  • dispatch_async places a block on a queue and continues immediately

Finding concurrency bugs in Objective C

In code that uses multiple queues, one common concurrency bug is deadlock. Deadlock can happen when there is contention between two queues.

One example of deadlock is when blocks on two separate queues make dispatch_sync calls to each other.

Let’s say we have two queues, the sending queue and the manager queue. The sending queue has a method called beginTransaction, and the manager queue, which oversees both sending and receiving, has methods for managing crypto keys, including one called updateCryptoKey.

beginTransaction looks like this:

make sure the transaction is valid
dispatch_async(sending queue, ^{
    ensure no other transactions are in progress
    get crypto keys for this transaction
    put the transaction in our data structure
    start the transaction
});

updateCryptoKey looks like this:

make sure key being submitted is valid
dispatch_sync(manager queue, ^{
    is there an existing key?
    if not, add the key
    if yes, remove the existing key and add the new key
});

There is a potential deadlock between the sending queue and the manager queue. Each block has a dependency on the other queue. For the block in beginTransaction, the step of getting the crypto keys will do a dispatch_sync to the manager queue. Meanwhile, for the block in the manager queue, the step of removing the existing keys will do a dispatch_sync to the sending queue as part of cancelling any existing transactions under the old key.

These queue dependencies aren’t immediately obvious, because they are hidden behind function calls.

When finding deadlock between queues, it doesn’t matter how a block got placed on a queue. Here we have one block that was placed using dispatch_async, and one that was placed using dispatch_sync. What matters is what happens once that block is running. Since these two blocks are on separate queues, they can be running simultaneously. Then one of them does a dispatch_sync to the other, and it waits, because that queue is not free at the moment. Then the other does a dispatch_sync back to the first, and it waits too, because that queue isn’t free either. This is a deadlock.

Three weeks with a smartphone

Three weeks ago, a shiny new Galaxy S4 arrived in the mail. I purchased the Samsung Galaxy S4 GT-I9500 32GB (unlocked) on eBay. The phone was released about a year ago, but I found a vendor who was selling it new. When it arrived, it had Android 4.3 on it. Recently, an update arrived to my phone for Android 4.4, an OS which by now is 6 months old.

Initial setup

There were a lot of questions and informational boxes, both from Samsung and Google. I was a little overwhelmed. Later on, I went back into the different apps and looked more carefully at the settings.

Many apps I used on my iPod were also available on Android. I installed Facebook, Twitter, Dropbox, ESV Bible, Olive Tree, Springpad, Pleco, Webster’s dictionary, Google authenticator, MPR Radio, and Crashplan. A few apps I had not been able to use on the iPod, because they only supported iOS 6 and higher. This list included Amazon MP3, and Bandcamp, though I don’t use either of them often. Apps I installed that were not on iOS include Firefox and F-Droid, which I’ll talk more about later.

Comparison with iOS

Before owning the Galaxy S4, I owned a 3rd generation iPod touch for 2 years. It wasn’t a phone, and it didn’t have a camera, but it did a lot of the things a smartphone does, provided I was in wifi range. I installed a number of apps and used Apple’s included apps as well. When I bought the S4, I had to get used to the differences in the user interface.

Some physical differences that stuck out to me:

  • Don’t rest your thumb on the bottom edge of the phone, you’ll bump the back button. I had to get used to holding my Android differently than my iPod touch.
  • The sleep button is on the side instead of on top, which means that there’s no side to rest the phone on when it is horizontal.  Which buttons do you want to mash if watching a video in widescreen?
  • The sleep button also becomes a shutdown menu if you long press it (same as the iPod), but the definition of “long” is much shorter on Android. I’ve seen that menu way too many times.

Some software differences:

  • Rearranging icons on the home screen is much different.
  • Launching apps and going home feels slower on the Galaxy S4. This is a little disconcerting, considering the S4’s hardware is 4 years newer.
  • Two different photo apps: Photos and Gallery. Apparently Google is trying to shift over to Photos.
  • The lock screen clock widget is inaccurate half the time. The little numbers in the upper right are always right, but the big numbers aren’t always right. This is unacceptable.
  • I like not having to install iTunes in order to transfer music on the phone.
  • Apps live in two places: In the Apps list (shows all your apps), and possibly on your home screen (where you can add widgets, arrange to your heart’s content)

Overall, iOS feels more integrated. Apple has had more time to refine their product. The lock screen clock widget and the apps living in two places are excellent examples. Another example is system updates. For Android, when you get an update depends on the device you’re using and which carrier you have. For iOS, you get the update when it comes out.

On the other hand, Android is much more customizable. I installed F-Droid, a 3rd party app store with only open source apps in it. So far I’ve installed KeePassDroid, SatStat, and FillUp from it. It makes my inner free software person happy. You can also install custom keyboards, root your phone, and even replace the firmware, things I haven’t yet been adventurous enough to do.

If my readers have any thoughts about iPhone vs. Android, I would welcome them in the comments.