Hack hack hack...

An open journal-- some of it written for you, but most of it is for me.


Weekly 1 on 1s are not enough. Maybe if I did them better they would be, but mine are all on Fridays and often I’m not able to tease out anything more than the day to day updates and feelings of the past week. That’s not to say that I’m going to stop, 1 on 1s keep me connected to my reports and even if 1 out of every 5 is a breakthrough session then it is time very well spent.

The problem that I see in 1 on 1s as I run them is that it is hard to focus on the longer arching themes on a weekly basis. For whatever reason, it feels awkward to ask about career goals, work fulfillment, etc. with such regularity. Enter the quarterly. I’ve just completed my fourth attempt of quarterlies (not including the annual review). I’m happy with the conversations and the depth of the issues we discuss in those session but my attempt at this didn’t start very well.

Here were the set of questions from the first quarterly survey which I conducted using google forms:

  • How happy are you in labs?
  • I feel like I’m growing my skills
  • I get clear and frequent feedback about my performance?
  • Given the products we are building, what types of things do you want to work on?
  • What skills (on or off the keyboard) do you want to improve that you don’t see an opportunity to do in your current role?
  • I understand why we are building Learn and the related apps
  • If you answer that you get it, please summarize why we are putting so much work into Learn.
  • If you answered you don’t get it, please tell me what needs further explanation.
  • Anything else you want to discuss?
  • What is one thing that would make you happier or more productive?

This caused a lot of anxiety. Why am I doing this? What was I going to use this information for? Many of those first conversations were stilted, even confrontational. Someone actually took this time to give his two week notice. It wasn’t pretty. Even so, I was able to battle through these difficult conversations and pull out a lot of agenda topics that we were able to resolve as a group. This made it all worthwhile. Gathering the team in the room to talk about issues that were affecting all of us and re-focus our direction was incredibly fruitful. I also followed up with the individuals that took issue with the set of questions I was asking and had them help me craft a questionnaire that was easier for them to swallow.

Three month later the process went much smoother. Here were the revised questions.

  • I feel like I’m growing my skills
  • What is one thing that would make you happier or more productive?
  • In what ways would you like to grow your skills? What kind of support will you need?
  • Do you feel like you’re getting enough clear feedback?
  • How do you feel about the Lab’s processes in general?
  • Given the products we are building, what types of things do you want to work on?
  • I find the work that I do full of meaning and purpose
  • I am proud of the work that I do for my team
  • The work that I do is challenging
  • How would you rate yourself in the following 4 tenets of our “shipping culture” (circle one for each category):
  • Velocity
  • Quality
  • Ownership
  • Communication

This one clicked much better. I got great responses and we had a great team discussion. Processes changed, people were engaged and excited to debate with each other. I was able to present the group with statistics on aggregated stats on how challenged individuals felt and where we needed to improve as a group.

A year later, this is the best thing I think I do as a manager. We ask similar long form answers but have dropped the ratings of the department values in lieu of the company values (see future post on Value Based Assessments). With a young team, it isn’t uncommon for me to see career aspirations change quarter along with engagement and performance. I’ve found these quarterlies to be better discussions than the annual review. Some reasons might be, it isn’t as formal or mired in the connotations of a scary end of year process. I use google forms rather than some HR software, which seems pretty natural and lightweight for devs. I choose a venue that seems more informal but is still off-site (recently I’ve been camping out at Au Bon Pain). And yet, much of this conversation is spent on discussing performance, areas of improvement, how to grow, resetting expectations and ways to improve the team and product – all the things that I would imagine a good annual review process is supposed to do. This cycle I’ve scheduled 90 minutes for each session but not one actually was completed in time. People are talking for 2 to 2 ½ hour stretches even though it is basically the same set of questions that I’ve used for the last three rounds. This is a huge investment of time. All said and done I will have done more than 30 hours of quarterlies before preparing a deck we can discuss as a group. But this is working and the conversations have improved every quarter.

Even with its rocky start, quarterlies have served us well. I would have never known many of the team’s process pain points without these conversations and it has saved me when performance slips so that I can get on the record to address it quickly. If annual reviews are broken my first guess would be that even if they are conducted well, they are just too infrequent. Things on my team move too quickly to address on a 12-month cycle. This is my best shot at making it better.

When I Didn’t See It in the Interview

Raw intellect isn’t enough. Just like product market fit we need to see person-job fit. How can we test it? Good people with drive and patience for change and a healthy sense of duty seem to be able to adjust to nearly any job for a short period. We can all do any job for six months and knock it out of the park.

I think about a particular interview where I left so excited about the candidate. They were quirky, but thoughtfully engaged. They grasped what we did here and why it was important. They thirsted for new knowledge and challenge. They were young and ambitious. No work experience of any kind.

But when he arrived it was an utter let down. The focus wasn’t on getting as good as possible as quickly as possible but rather maintaining balance at all times. Never pushing himself to be in the trenches with his brethren in times as the pressure bore down on them or let the passion take him deep into the night when we feel the torment of an unfinished idea demanding completion.

All the raw materials were there. What did I miss? If we hire someone with no work history, does the onboarding process need to be different? Do we need to teach them not only how to do the job but also how to be an employee? What expectations did we set to encourage him to rise to be great?

I cannot move past my disappointment. I signed off on him. I had high expectations. Though not my direct report, I provided course corrections. As time continues to march on the disappointment builds. I notice the small improvements but never the grand about-face for which I hold out hope. That one day when he will wake up, open his eyes to observe and finally be dissatisfied with his mediocrity.


Transparency begets trust and trust begets transparency. It isn’t easy and it feels unsafe to bare your process and sometimes soul. Talking about the thing you least want to talk about has been something that has helped our team address the weirdness that exists between our people and processes. But it wasn’t always like this. We used to ignore or only privately address what needed to be discussed the most.

A few months ago, during a period when a lot of new hires were starting and suffering from imposter syndrome, I tried to reinforce our culture of transparency and honesty by telling my team that I wouldn’t hire myself for our team. I assume that isn’t something that most managers admit and I explained my rationale. I’m not a strong enough coder to hang with them. I don’t complement the personalities we have. I don’t bring enough of a unique perspective as an individual contributor. It pains me to even write this, let alone tell my teammates that this is how I feel. Doing this led to a bunch of other team members describing their version of imposter syndrome and clearly put the junior members at ease. That is all to say, that saying the thing I least wanted to say helped build trust with the newest folks and let them know what I worry about which means they can be more sure when I’m confident. Always acting one way or another isn’t natural. Transparency, therefore, may start with the act of humanizing yourself and being vulnerable.

Team buy-in is tough to earn. It is much easier when the process is created and enforced by the team. As the manager, I can try to keep it on guardrails, but determining it and enforcing it myself would be a mistake. Maybe this isn’t sustainable with a bigger team. What if all the laws in this country were determined democratically by the entire population. It would be way too heavy. But with a team of 13, this is still possible and it is so much stronger when the policing is done by the team rather than me.

Transparency communicates trust. Exposing our vulnerabilities as an individual or an organization encourages candor and self-reflection. Putting a positive spin on everything doesn’t equate to boosted morale because it leads to whispers, eye rolling and eyebrow raising in the hallways. It is human nature to latch onto weaknesses, failures, and negatives and so if these deficiencies are not squashed publicly then they fester. They use rumors as sustenance and mutate in unpredictable ways. Talking about the hardest things right away is painful, but a preferable alternative to passively deferring to hearsay.

Transparency is hard. Generals must be able to make decisions. Soldiers must follow orders. We run into trouble is when soldiers don’t buy into the purpose or mission. Even the most ardent followers will lose enthusiasm over time if they don’t feel like they can influence the decision making process. And so what we find is people will do enough to keep their job. They half-heartedly go through the motions. In short order, that becomes the norm and apathy is a difficult virus to contain. And so while we can’t ask everyone for their input on every decision, if we know what is important to our people, we can ask them at the right times. This requires the decision maker to actually know their people and that takes a serious investment. Do you have time for that? I guess that’s up to you, but second guessing, rumor squashing, and low-morale also eats up time so maybe this would be worth some investment.

Peer Mentorship

Next week I’m going to introduce a new 1 on 1 system on our team. I currently have 8 reports and the other manager on our team has 5. The load of weekly 1 on 1s is quite large if we are truly doing a legitimate check-in. And so, I’d like to try out a system of peer mentorship where peers conduct one on ones with each other for a week to 2 weeks a month. This means we will need to spend time training the team on how to conduct 1 on 1s which I will assume will force us to consider how we currently conduct our 1 on 1s and how they could be better.

Peer mentorship organically already exists on the team. We see natural gravitations along lines of technological specialities and personality types. I’ve done my best to find assignments for these pairs to share a chunk of time working together and I’ve always been impressed with the results. Formalizing this process through this peer mentorship check-in system should further reinforce that natural alliance without forcing devs to be people managers.

We’ll see how this experiment works out, but I’m excited to give it a try. Trusting team members with the task of developing their peers has almost always led to positive results. I expect the same here.

My Take on Maker Versus Manager

I toed the line for months trying to code a little and be the manager I wanted to be. When the team was at 8 I could find time to block off a morning without meetings or distractions. I could be a hybrid. As we grew to 12 it became untenable. The code I contributed was copy and CSS changes. Barely anything that was worthwhile from a contribution perspective. Letting go was the healthiest thing I could do. I’m not a coder anymore and I admitted that to my team in a frank conversation about imposter syndrome a few weeks ago. I’m a conductor. My job is to make sure the symphony continues to play in harmony. To draw out the sounds and rhythms of my individuals through 1 on 1s, quarterlies and conversations in the hallways.

Being an effective hybrid is possible. We have one. He is a great individual contributor and without fail he does his 1 on 1s and still pushes a ton of code. It works and he is getting the reps he needs to be a future CTO. Taking him off the keyboard would make him miserable and so he’ll toe the line for a while. He has 5 reports and I’m wary to give him more.

I’ve heard coders talk about how bad managers are out of touch because they don’t build anything anymore. I agree, which scares me. Which is why I want to try an experiment. I went on a paternity leave in October for a full month. I totally unplugged and trusted my lieutenants to carry the load. It went fine. No fires. Nobody quit. No month long rabbit holes anyone fell into. There was some maintenance and fine tuning to be done upon my return and some of the project assignments were off, but overall things went well. Meaning that if I disappeared for another month things would likely be fine again. Meaning I could become a dev for a month and let my lieutenants run the show again. I think it would be hard for me to resist my natural inclination to push, nudge and otherwise direct how the team runs, but what might happen if I stop going to all the high level meetings? We’ll find out. I’m going to propose we try it next month.

To be the manager my people deserve for a team of certain size I needed to let go of my drive to code. Sure I can nibble on small projects, but my days of plugging in and zoning out are seemingly over. Hybrids can be of value, but if you are running the show and managing anything larger than a team of 7-8 then you are doing yourself and your team a disservice by trying to focus on anything but your people.


I’ve read a lot of articles about onboarding, but I’m not sure I come away with anything that actually changes my process. We all know that onboarding is important. Given how many juniors are on our team, it is essential for them to be brought up to speed as quickly as possible so that they have a chance at being productive.

Onboarding starts during the hiring process. This is why compensation negotiation is so tricky. People need to be excited about starting. A difficult negotiation becomes very personal. This is the purpose agents play. They are able to distant their clients for a painful negotiation so that it is less personal.

After the candidate has accepted, if given the opportunity, I really push for the new hire to take a good amount of time off. I refer to these as “bookends” and I believe there should be a good amount of space between her last experience and her new one. A new hire is usually surprised by this, but it sets the tone for a more caring managerial relationship than they have experienced before. The message is clear. You are a hard worker, you deserve a break. We will wait for you. Come when you are ready.

For the purposes of this article, I’m going to focus on junior hires because I think their onboarding process is likely more complicated than their senior counterparts. Juniors need a ton of attention when they arrive. I mean like daily check-ins, scheduled lunches and coffees and firm direction on what code to explore. I start with the onboarding readme on our team wiki. We also have a dev expectations readme.

I’ve pushed new hires to improve the docs as they read them with so-so results. The truth of the matter is, they can’t recognize what they need to know until a few weeks in and by they their attention has turned to feature development. Maybe asking them to take another scan after a couple months would be an effective way to improve the system.

The first few 1 on 1s are critical. This is a time to allay fears about imposter syndrome and provide a lot of encouragement upfront. Juniors have never seen a code base as large as ours and they are intimidated. Reminding them it is the exact same, there is just more of it will not be heard the first few times you say it. It will need to be repeated a dozen or so times before it sticks. You belong. We are confident you belong. We wouldn’t have hired you if we weren’t. We don’t make hiring mistake. Whether it is true or not, that’s the message and willl give you the best shot at success.

The first few assignments are also very important and I’ve learned to not be so cavalier with them. Here are some of my favorites:

  • Specs: There are always things to improve in the test suite and giving the new hire some space to go down a few rabbit holes will familiarize her with how the system works while at the same time immediately adding value.
  • Refactors: Improving your most incomprehensible code immediately makes the new hire a hero after they can untangle your mess. Again, giving him some space to explore how the system interacts is time well invested.
  • Small feature win: Shipping something immediately makes everyone feel good. Not only are they able to quickly get a win on the board, but they also can immediately feel the builder’s high and pride of owning a user facing feature.
  • Pairing: Pairing can be combined in all these scenarios but pairing takes the pressure off of the new hire by making sure they aren’t going it alone. Insisting the new hire to drive anecdotally also seems to increase confidence and ensures she doesn’t become a passive observer.
  • Onboarding the next noob: Allowing a new hire to onboard the next new hire has been really effective for my team since it proves how much he has learned about the code and our process. While the timing is a key element, I’ve seen confidence levels dramatically shoot up after shepherding a new hire.

There isn’t anything all that novel here. I think giving a new hire a lot of attention and making sure they don’t flounder too much is the basic goal (a little flopping around is OK). Even if they are working on a project, allowing for an orientation period takes the pressure off and allows them to explore the code. This is time well spent. For a new junior hire, I’ve made the mistake of putting deadlines around that first project with disastrous results.

Ramping up not only helps a new hire feel productive and competent, it also affects our team dynamic. We need all of our team members to participate in our difficult discussions and if a new hire lacks confidence in their code contributions they also sideline themselves in our team dynamics. Poor onboading is an opportunity lost to build rapport and establish confidence while good onboarding usually leads to individual comfort and immediate buy-in. So while it can be very time intensive, for me it has been worth the investment.

Linchpin by Seth Godin Notes

  • Notes:
    • Obedience is no longer rewarded - 4
    • We weren’t born to be cogs, we were trained to be cogs - 6
    • schools should teach: how to solve interesting problems, how to lead - 47
    • Emotional labor - 57
    • Jean baptist Colbert - 63: did he write down any of his thoughts?
    • Acknowledge fear, then proceeds - 65
    • Tom peters - 83
    • No one cares how hard you work- 95
    • Someone can do your job better and cheaper, not your art - 97
    • Artists are optimists- 98
    • Creativity is the instinct to produce - 102
    • Shipping -101-103
    • Steve McConnell - poorly timed thrashing 104
    • Elizabeth Gilbert Ted talk - 106
    • War of art, Steve pressfield- 107
    • Bio of lizard brain -109
    • You are a winner because you learn from losing - 115
    • 3 biological factors that drive job performance: social intelligence, fear response, and perception - public speaking brings together all 3 - 124
    • Fear is the most important emotion we have - it kept our ancestors alive. It dominates all other emotions. 124
    • Symptoms of lizard brain - 127
    • Leo babauta zen habits - 135
    • Shenpa: Tibetan word that roughly means scratching the itch - 138
    • Planing with the index card technique 146
    • Permission marketing? - 148
    • Pizzeria owner made shirts with bad Yelp reviews - 152
    • Damaging business book - Robert ringer - looking out for number one 153
    • Linus will never need to worry about finding work because he gave away Linux - 162
    • Sunny bates - 166
    • Clay shirky, Dan rushkoff - 169
    • Richard Branson - chartering a plane - 180
    • Can’t get attached to the objects of your attention -184
    • Art is defined by the fact I can’t tell you how to do it - 188
    • Your product should match your marketing, not the other way round -201
    • Deanna Vogt, Corp coach -202
    • Resilience, Ralph Waldo Emerson - 208
    • 5 elements of a personality: openness, conscientiousness, extraversion, agreeableness, and emotional stability - 210
    • Honest signals, book - 214
    • Dale Carnegie - 217
    • Creative -
    • Personal, original, unexpected, useful.
    • Unique creative - domain knowledge, position of trust, generosity to contribute back - 219
    • Org obey newton’s laws: a team at rest stays at rest - 221
    • Lester Wunderman: invented direct marketing - 222
    • Focus on making change down not up. Interacting with customers and employees is easier than bosses and investors - 229
    • Pranja - see the world objectively - 235

Patterns of Enterprise Application Architecture


“Architecture” is a term that lots of people try to define, with little agree- ment. There are two common elements: One is the highest-level breakdown of a system into its parts; the other, decisions that are hard to change. It’s also increasingly realized that there isn’t just one way to state a system’s architec- ture; rather, there are multiple architectures in a system, and the view of what is architecturally significant is one that can change over a system’s lifetime. p. 1.

The subjectivity comes in here as well because, if you find that something is easier to change than you once thought, then it’s no longer architectural. In the end architecture boils down to the important stuff—whatever that is. p. 2

Responsiveness is about how quickly the system acknowledges a request as opposed to processing it. This is important in many systems because users may become frustrated if a system has low responsiveness, even if its response time is good. If your system waits during the whole request, then your responsiveness and response time are the same. However, if you indicate that you’ve received the request before you complete, then your responsiveness is better. Providing a progress bar during a file copy improves the responsiveness of your user inter- face, even though it doesn’t improve response time. p. 7


There’s no generally accepted definition of a pattern, but perhaps the best place to start is Christopher Alexander, an inspiration for many pattern enthusi- asts: “Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice” [Alexander et al.]. Alexander is an architect, so he was talking about buildings, but the definition works pretty nicely for software as well. The focus of the pattern is a particular solution, one that’s both com- mon and effective in dealing with one or more recurring problems. Another way of looking at it is that a pattern is a chunk of advice and the art of creating patterns is to divide up many pieces of advice into relatively independent chunks so that you can refer to them and discuss them more or less separately. p. 9

Making a choice

Growing Object-Oriented Software, Guided by Tests

Object-Oriented Style

We value code that is easy to maintain over code that is easy to write. Implementing a feature in the most direct way can damage the maintainability of the system, for example by making the code difficult to understand or by introducing hidden dependencies between components. Balancing immediate and longer-term concerns is often tricky, but we’ve seen too many teams that can no longer deliver because their system is too brittle. p. 47

Encapsulation and Information Hiding We want to be careful with the distinction between “encapsulation” and “information hiding.” The terms are often used interchangeably but actually refer to two separate, and largely orthogonal, qualities: Encapsulation Ensures that the behavior of an object can only be affected through its API.It lets us control how much a change to one object will impact other parts of the system by ensuring that there are no unexpected dependencies between unrelated components.

Information hiding Conceals how an object implements its functionality behind the abstraction of its API. It lets us work with higher abstractions by ignoring lower-level details that are unrelated to the task at hand. p. 49

Our heuristic is that we should be able to describe what an object does without using any conjunctions (“and,” “or”). If we find ourselves adding clauses to the description, then the object probably should be broken up into collaborating objects, usually one for each clause. p. 52

Context Independence

While the “composite simpler than the sum of its parts” rule helps us decide whether an object hides enough information, the “context independence” rule helps us decide whether an object hides too much or hides the wrong information. p.54

Achieving Object-Oriented Design

Interface and Protocol Steve heard this useful distinction in a conference talk: an interface describes whether two components will fit together, while a protocol describes whether they will work together. p. 58

Kernighan and Plauger attribute the idea of pipes to Douglas McIlroy, who wrote a memo in 1964 suggesting the metaphor of data passing through a segmented garden hose. It’s currently available at http://plan9.bell-labs.com/who/dmr/mdmpipe.pdf. p. 66

The Sniper Makes a Bid

Defer Decisions There’s a technique we’ve used a couple of times now, which is to introduce a null implementation of a method (or even a type) to get us through the next step. This helps us focus on the immediate task without getting dragged into thinking about the next significant chunk of functionality. The null Auction, for example, allowed us to plug in a new relationship we’d discovered in a unit test without getting pulled into messaging issues. That, in turn, meant we could stop and think about the dependencies between our objects without the pressure of having a broken compilation. p. 136

When the facts change, I change my mind. What do you do, sir? —John Maynard Keynes p. 172

Computer Science According to Spencer

What is it

Big O

  • used to classify algorithms by changes to the inputs
  • O(1) - constant time - kilometers to millimeters
  • O(log n) - opposite of exponential growth, searching binary tree
  • O(n) - iterating over an array
  • O(n log n) - good sorting algorithms
  • O(n2) - bubble sort (bad algoritms)
  • O(2n) - the chess board, example doubling something


  int rectangle_area(height, width) {
    int area = 0; // 1

    for(int i = 0; i < height; i++) { // 2*height + 1
      for(int j = 0; j < width; i++) { // 2*height*width + height
        area++; // height*width

    return area; // 1

  complexity: 3*height*width + 2*height + 3
  order: O(height*width)


  Constant time. O(1).

  int halves(n) {
    int count = 0; // 1

    if(n % 2 == 1) { // n
      n = n - 1; // n

    for(int i = n; i > 1; i = i / 2;) { // n + n + n
      count++; // n

    return count; // 1

  Complexity: 6n + 2
  Order O(log n)

  int bacteria_generation(days) {
    int total_population = 1; // 1
    int current_population = total_population; // 1

    for(int i = 0; i < days; i++) { // 1 + days - 1 + days - 1
      current_population = total_population; // days - 1

      for(int j = 0; j < current_population; j++) {

    return total_population;

  Order: O(2n)

  int max(array) {
    int max = array[0]; // 1

    for(int i = 1; i < array.length; i++) { //n + 1, [cost of determining array length](http://stackoverflow.com/questions/5872570/is-fixed-array-size-on-or-o1-in-space)
      if(array[i] > max) { // n
        max = array[i]; // potential n

    return max; // 1

  [3n + 3 complexity]


  int max(array) {
    int temp; // 1

    // sort the array in ascending order
    for(int i = 0; i < array.length; i++) { // n + 1
      for(int j = 0; j < array.length - 1; j++) { // (n + 1)(n + 1) -> n^2 + 2n + 2
        if( array[j] > array[j+1]) { // potentially n(n + 1) -> n^2 + 2n + 2
          temp = array[j+1]; // 1(n + 1)
          array[j+1] = array[j]; // potentially n(n + 1) -> n^2 + 2
          array[j] = temp; // 1(n + 1)

    return array[array.length-1]; // 1

  [3n^2 + 7n + 9 complexity]

  The first is more efficient.

  6. Which algorithm, foo or bar, is faster when when n is 10? 100? 1000?

  int foo(n) {
    int sum = 0

    for(int i = 0; i < n + 500; i++) { // 510, 600, 1500 operations

    return sum;

  foo(10) = 130,305
  foo(100) = 180,300
  foo(1000) = 1,125,750

  int bar(n) {
    int sum = 0

    for(int i = 0; i < n; i++) { // 10
      for(int j = 0; j < n; j++) { // 10
        sum++; // 1

    return sum;

  100, 10,000, 1,000,000

  bar is less work at 10, foo for the others