Recent Posts (page 38 / 70)

by Leon Rosenshein

Forward Looking

Tis the season. The season for perf. But this one is a little different. First off, we've been out of the office for ~9 months. Second, we haven't done this for a year. Third, the situation is more fluid than usual. So yeah, if this feels weird, that's because it is.

That doesn't mean it's any less important though. In some ways it might be more important. Because perf season is not supposed to be a personal sales pitch aimed at maximizing your total compensation. What it really is, is a specific point in time to stop, look forward and backward, reflect on where you've been and where you're going, and think about the next steps required to get there.

I talk about customer value and product benefits a lot, and it's always important to know who the customer is and what the product is. In this case, you're the customer, and your career is the product. So all of the things that go into adding value and building benefits apply in this situation. As does the approach.

First and foremost, what's your vision? Where do you want to be in 2 years? 5 years? 10 years? How will you know when you've achieved your vision, and what will life be like then? That sets your north star.

Second, where are you right now? What are your strengths? Weaknesses? What have you accomplished along the way? What impact, on yourself, your team, and your work goals have you had? What are you still working on? When you look at this through the lens of Perf Season this is what you did over the last 12 months. Think of it as a sprint retrospective. What went well? What was delivered? What could be better?

Third, look at the gap between where you are now and where you want to be. That gap is the opportunity to create value. Identify the missing/weak components and figure out what you can do to make them better. Every new skill or ability is a feature. You can put those features together as a benefit and benefits add value. During Perf Season this is the career planning part. Or you could think of it as sprint planning. The gap between now and the vision is your backlog. What items off the backlog are you going to work on this year? How do they tie together into sprint goals and add value to you, the customer?

Because, when you get down to it, Perf Season, while it has lots of uses for your employer, whoever that is it will be, it's always about you. In sprint terms, you're the Product Owner, so you have a lot of say in what gets done and not done. You have a voice in the process all the time, but right now your voice is especially important, so make yourself heard.

by Leon Rosenshein

Gooooaaaallll

We do sprints, which come from Scrum. And Scrum has artifacts. There are 3 official artifacts, the product backlog, the sprint backlog, and the "Potentially Releasable Product Increment". That's it. The only 3 artifacts of Scrum. Not tasks. Not acceptance criteria. Not burndown charts. Not velocity.

However, there are lots of things that get created when you implement Scrum (or scrum-like development). Such as tasks. And boards of tasks. And Acceptance Criteria. All critical things if you want to make it work. And what is that "Potentially Releasable Product Increment" thing anyway? What is it for, and what do you do with it if it's only a potential.

That increment is why we're here. It's the customer value we're supposed to be providing. One of the goals of agile development in general, including Scrum, is to increase the velocity at which value is added, so that total value over time is maximized. And that increment is the embodiment of the value.

Which means that the product increment is really the focus. It's the thing you want to get done. It's the thing that ties all the items on the sprint backlog together as a goal. You might have more than one if you have multiple things you want to improve at once. It might be that you can add more value by improving in 3 areas at the same time than by doing more in any one area. But either way, your sprint goals tie things together.

So stop thinking about your backlog as a series of unrelated tasks and start thinking about how those tasks represent a smaller set of goals that provide customer value.

by Leon Rosenshein

Is 2020 Over Yet?

As I've noted before, I'm a mechanical and aerospace engineer by training. I think a big part of why is what I grew up reading. Books about competent technical folks who just got things done. Books like Thunderbolt, Flying Fortress, The Dam Busters, and The Right Stuff. Later it was Hackers, The Cuckoo's Egg, and Surely You're Joking, Mr. Feynman!

One of the common themes in those books was someone who saw something that needed to be done to meet a need, and then did it. People who were just that good at what they did. Whether it was the aircraft pilots, designers like Barnes Wallis, or self-taught cyber sleuth and brownie maker, Cliff Stoll.

One of the people that really stood out was Chuck Yeager. Aircraft Mechanic, Fighter Ace, Test Pilot. According to the stories he was also a pretty good leader. When they asked him to fly the X1 in 1947 he just did it. He didn't ask for extra money or make excuses. It was his job, so he strapped on the rocket and did it. Over the next 30+ years he made a name for himself around Edwards AFB by quietly doing his job and helping others do theirs. And outside the aviation industry no one knew who he was until the movie, The Right Stuff came out, and even then, John Glenn and the rest of the Mercury 7 got top billing. I actually got to meet him when I was working for a small aerospace company in the early 90s. There were a few retired test pilots there and he came around occasionally. He certainly had some good stories to tell.

General Yeager passed away yesterday. The world is a poorer place without him. He inspired me as a child and early in my career. Even today, as I deal with all of the churn of 2020, I sometimes thing about Gen. Yeager and the other "heros" of those books and how, even when things got weird, they kept the long term vision in mind while focusing on the task at hand and got stuff done.

G-dspeed Gen. Yeager.

by Leon Rosenshein

Owning Your Code

Code ownership. Good or Bad? It must be good because github has a CODEOWNERS file, and we have `METADATA.yaml`, right?

Like everything else, the answer is, it depends. In this case it depends on what you mean by code ownership. Because code ownership can mean different things to different people. In this case I'm not talking about who owns the intellectual property. I'm talking about the responsibility for code. Not just writing, but maintaining and extending it.

There are a handful of models to choose from. The simplest is strong individual ownership. For any given piece of code (application, library, module, service, etc.) there is exactly one person who owns the code and is solely responsible for making changes. That works. Clarity is always good, and you always know who's on the hook to make something happen. But it's less than ideal when you actually want things to happen. Especially if there is more work than the designated individual can do. That person becomes a bottleneck.

Another option is team or small group ownership. In complex systems this brings the benefit of reducing cognitive load while mostly removing the bottleneck(s) of individual ownership. If you're not part of the team you just make the function/network call and assume it's going to work. You don't know or care what's on the other end. You just do your day job and throw problems/issues over the wall and the team will pick them up and deal with them. It does make your job easier, and, because there can be multiple people working on the other side of the wall it is much more scalable than individual ownership. But the team on the other side of the wall isn't infinitely growing, and you're probably not the only one throwing things over it, so when your issue is dealt with is still pretty undetermined. There's still a bottleneck, but it's not as bad as it was.

Then there's collective ownership. Everyone owns everything. Have a problem? Just fix it. Don't like the way something works? Fix it. Need new functionality? Add it. After all, we're in a monorepo, so it's easy and it solves your needs. Perfect. Or not. Everyone owns everything is just another way of saying no one owns anything. That's anarchy, and we certainly don't want that.

Personally I'd like to see a modified version of team ownership. Reducing cognitive load is important, so I strive for that. And complex systems are just that, complex. Unless you've been thinking about something deeply for a long time there are almost certainly strange interactions and emergent behavior in a system you need to be aware of when making changes. And the only way to get those insights is through experience. So team ownership, as in responsibility for how the sub-system fits into the greater whole, makes a lot of sense. The team knows the sub-system, the tools, the customers, and the gotcha's. They're usually the right ones to make changes, so they should do it.

But not always. Sometimes they're busy. Sometimes your priority isn't theirs. Sometimes they don't understand you. In those cases the right thing to do is make the change yourself. Then make a request to the team to pull your changes in. A Pull Request if you will. Then the team can evaluate the PR, bringing their experience and plans to the evaluation, and then accept the change or make suggestions about how it can be improved. And they need to do that quickly. They might even iterate directly with the author of the PR to make sure it meets even more needs than the author had originally intended. And that's good for everyone.

Or, in other words, we're all responsible for getting our own work done, and sometimes that means making changes to parts of the codebase we don't normally work in. And in those situations we're all responsible for working with the experts in that area to make the right changes, not just the changes that benefit us, regardless of the cost to others.


by Leon Rosenshein

List Comprehension

The other day I was in a class on `bazel.` Lots of interesting stuff there, and I got a lot out of it. Concepts and "idiomatic" bazel. Because everything works better when you are working with a tool in the way the designers/implementers intended. But that's a topic for another time.

In the class the instructor pointed out a few websites that claimed to be "The best list of ..." or "A well curated list of …" and said that in his experience, in those cases curated generally meant that it was the first N things a google search returned on the day the list was built. That matches my experience as well, although I'd add the other type of list, the advertising list, where vendors (using the term loosely) can pay to have their entry added to the list. There's sometimes good info in those lists, but it's on you the consumer to find the gems.

But that's not always the case. Every once in a while you come across a curated list that really is well curated. A list where each item has a lot of value by itself, and the list in total is worth even more. One of those lists is def programming: Quotes about coding. 329 (as of today) quotes, and each one gets you to think about some fundamental aspect of programming and development in general. Taken together they can form a great foundation to build on.

Getting on that list is now one of my life goals.

by Leon Rosenshein

Outputs vs. Outcomes

Right now we're in the middle of Q1 planning and the 2020 perf review cycle. One forward looking, and one backward looking. One is team/org/company related and one is personal. So what do they have to do with each other, and more interestingly, how do they relate to "outputs vs. outcomes"?

First, they're temporally connected. perf always follows planning. And a big part of this year's perf review is based on the planning from last year. Next year's perf review will be guided by the planning we do now and over the next year. Because a big part of your perf review is around how well you met your (sometimes changing) goals.

Not just a review against those goals, but the impact of those goals. This year more than previous, the connection between perf reviews and impact is clear. Because impact is much more than hitting your dates, although that's still important. Impact is not working on everything, it's finishing the right things. Those things that help your team, your org, and the company move faster. Not just faster, but faster in the right direction. That's having impact

And impact is where the difference between outputs and outcomes matters. Finishing a task, fixing a bug, and writing a design doc are all outputs. But they're not impacts. Don't get me wrong. Outputs are crucial. without outputs what are you spending your time on? But it's how those outputs roll up to outcomes that matters. It's how the outcome of those outputs impact your partner teams and customers.

So when you work on Q1 planning, it's not just what you could do, it's what you should do. What makes the most difference and has the most impact. And that rolls right into next year's perf review. Which means being thoughtful about planning not only helps the team/org/company, the outcome directly impacts you and your career.

So don't just do it for the team, do it for yourself.

by Leon Rosenshein

Input Validation

Little Bobby Tables might not be real, but SQL injection certainly is. And there are lots of ways to prevent it. And we should do all of them. From sanitizing inputs as soon as possible to using least privilege when making changes (why does the student management interface even have drop table permission?).

But this isn't about what to do. This is about where to do it. And I'm going to assert that it's as soon as possible. Because the sooner you can tell the user, the more context you can provide. Which would you rather deal with, a website that lets you type in answers to all 15 fields, then comes back with "Invalid input, please re-submit" or one that, as soon as you leave the age field, tells you that the input can only be numbers if you hit a character by mistake? I know which one I'd choose.

The same thing applies to client libraries that you might provide for your service. Very often there are options that can't be chosen together. Save time, a server round-trip, and all of the error generation/parsing by doing that on the client.

Yes, sometimes this means making a library that you can re-use both client and server-side. Or it might mean implementing the validation in multiple languages because you've got multiple clients. But it still makes sense.  You always want to delight your users.

Even (especially?) when they make mistakes.

by Leon Rosenshein

Abstractions vs. Interfaces

"Code against interfaces." Generally speaking that's a good idea, but let's be clear about one thing. But there's a problem with that sentence. What does interface mean? There are a couple of options

It could be the dictionary definition of an interface, which is "a point where two systems, subjects, organizations, etc. meet and interact" or, in computer terms, the public API. It could be a class, a service, a website, or something else. That means every C++/Java/<insert language> class is an interface. And that's certainly not what the intent is.

Or, it could mean the keyword interface, but C++ doesn't have an *interface* (unless you're talking about the MSVC extension). So that's probably not what interface means either.

What it really means is code against the abstraction of the model. The platonic ideal as it were. The things that boil a model down to its essence. The capabilities of a thing, or it's verbs.

Consider a logger. It has one verb, write. It takes a LogLevel and a String, and puts them somewhere for later access. When you're using a logger that's all you care about. You might write some convenience functions to help hide the definition of level, or to build the string from a template, but that's about it. And that's what you code against. In C++ it's an abstract class with only pure virtual functions. In Java its an interface. In Golang it's a type of interface.

Constructing one can be as specific and complicated as you need, or even provided via dependency injection, but when used you only know/care about the abstraction.

So, you're already coding against interfaces. In fact you can't help but do that. What you want to do is code against abstractions

by Leon Rosenshein

Decisions, Decisions, Decisions

Decisions are important. Who makes them. Why they're being made. When they get made. What the intended consequences are. What the unintended consequences are. Those are all important things about decisions. And there's another important thing that I didn't mention. That's how they're made.

Sometimes making a decision is complicated. Like choosing a U.S. President. First you have to jump through the hoops to get on the ballot. Then the eligible people vote in their states. The states count the votes, and the results of the people's vote is announced. Next, the state legislatures choose some other people (the number chosen based on the number of Senators and Congresscritters) who then go off in a room somewhere and have another vote. The person who gets a majority in that count is then declared to be President. Lots of moving parts, and it takes months.

Other decisions are simple. Most of us have a dominant hand, and when we need to write something down we use that hand. Not a lot of thinking about consequences, involving others, or taking time. Just pick up a pen and write something down.

At work we're all decision makers. The hard part knowing how those decisions should get made. In really broad strokes, there's a continuum, from autocratic to consensus to unanimity. A good way to approach it is to think about the scope of the decision. The name of a temporary variable in a loop in a function has small scope, and the developer should pick the name and use it. That would be the wrong time to call a meeting. collect ideas, and then discuss until everyone agrees that you've picked the perfect name.

On the other hand, if you're designing an API you need to ensure that your customers will actually want to use it. Again, you're not going to wait until everyone agrees that the API is perfect for all of their different use cases, but you should have consensus among the group that the API isn't unusable.

And on rare occasions, it can be necessary for everyone to be fully committed. If success requires everyone to actively participate then making sure everyone is in full agreement is critical. Those situations aren't common, but when they occur, everyone needs to agree. 

Of course, sometimes you can't get to consensus, let alone unanimity. It could be because of viewpoint, conflicting goals, or simply lack of time. In those cases, after trying to get consensus on the API, someone needs to, with understanding of the use cases, and ensure that what's truly required can be done, make an autocratic decision.

And regardless, once the decision is made, everyone needs to work with the decision.

by Leon Rosenshein

Take Time

One of the counterintuitive things about productivity is that you can be more productive overall by taking a break. And like everything else, this scales. Taking a short break during the day can clear out the cobwebs, let your mind process what’s floating around, and surface ideas that you were too busy to notice.

Similarly, holidays and vacations give you a slightly longer period to reset. There's more to life than work and, especially these days of WFH, having the time to not work is critical. Whether it's spending time with family, working on a hobby, having new experiences, or actually doing nothing (which is very different from not doing anything), it takes time to shift from work to something else. Personally I like cruises because of how disconnected from the rest of the world they are. One thing I've noticed is that it takes me 2+ days to actually get disconnected and start to get the benefits.

Then there's the sabbatical. 4 weeks for every 5 years of service. You can really do something with 4 continuous weeks. Everything from nothing (again) to starting something that's important to you. You could do a Feynman sabbatical in another field. Help out that NonProfit that needs your help. Whatever makes you happy.

I say this today because tomorrow is Thanksgiving Day in the US and Americans, particularly in the tech field, are notoriously bad at taking vacations and enjoying their holidays. Lots of reasons why and this isn't the place for them. But it is the place to remind folks that if tomorrow is a holiday for you, take it. And for the non-US folks, when your holidays come up take them.

I guarantee you the work will be there when you get back. And you'll be better equipped to do it.