Recent Posts (page 15 / 65)

by Leon Rosenshein

Tasking

As a general and President, Eisenhower had a big impact on the US. One of the more relevant to development is the Eisenhower Matrix. It breaks tasks down into 4 types and helps you prioritize which ones you should work on when. It also tells you which ones to ignore.

But what if 4 categories is too many for you? Shreyas breaks it down into 3 categories, giving you one less thing to remember.

TaskPriority

The three categories are:

  • Leverage: Tasks that have an inordinate amount of impact on the future. Do a great job on these. They’re the important ones and the time won’t be wasted.
  • Neutral: Tasks that are important, but the world goes on. Do what you can, but don’t obsess over them.
  • Overhead: Tasks that are overhead. Someone needs them done, so you need to do them. However, actively try to do as little as possible to meet the requirement.

If you do that you spend the time needed on the important tasks and get the overhead out of the way with minimal effort. You get to focus and your customer partners are happy.

Of course, the trick is to make sure you get the categorization right. Invert that and no one will be happy. Personally I prefer Eisenhower’s matrix, but I’ve seen many people be successful with this method.

by Leon Rosenshein

All Aboard

Today I started the latest chapter in my life. Just started my new job with Amazon, working on Just Walk Out technology. This is a big job change for me. It’s the first time in almost 25 years that I had to interview for a new job. It’s also the first time in almost that long that I made the transition alone.

Prior to Amazon I was at Aurora Innovation. I got there as part of an acquisition. Before that I was at Uber’s ATG subsidiary. I joined that organization, along with the rest of my team, as part of a re-org as Uber decided not to source its own maps from the ground up. I moved to Uber in a similar fashion. Microsoft decided that it wanted out of the map-making business and sold part of Bing Maps to Uber. While I was at Microsoft I spent most of my time in either the Bing Maps org or the Simulations org. Inside (and even between those two orgs) I moved to follow interesting work and advance my career. No (or very informal) interviews, and teams moved together.

This time it’s very different. I’m the only one moving. I had to interview with people I didn’t know and were unfamiliar with my work. Despite the fact that I’ve interviewed ~1500 people over the years, being interviewed was very different. Sure, the experience helped, and Amazon’s interview process was really smooth, but there’s still a lot of pressure.

And now, instead of working on the same things I’ve been working on, or learning new systems with the rest of my team, I’m drinking from the firehose. So much to learn. New technologies. New people. New processes. I can’t wait to see where it leads.

by Leon Rosenshein

Chesterton's Fence

I’ve mentioned Chesterton’s Fence in a couple of previous blogs, but I never did define it. Chesterton’s Fence is a parable about how lacking context can be dangerous. In his 1929 book, The Thing, Chesterton wrote:

In the matter of reforming things, as distinct from deforming them, there is one plain and simple principle; a principle which will probably be called a paradox. There exists in such a case a certain institution or law; let us say, for the sake of simplicity, a fence or gate erected across a road. The more modern type of reformer goes gaily up to it and says, “I don’t see the use of this; let us clear it away.” To which the more intelligent type of reformer will do well to answer: “If you don’t see the use of it, I certainly won’t let you clear it away. Go away and think. Then, when you can come back and tell me that you do see the use of it, I may allow you to destroy it.

Or, in other words, if you don’t know why something was done, don’t undo it without figuring out why it was done in the first place. Only when you know why something was put in place can you decide if it’s not be needed any more. Consider the typical bathroom sink.

Many of them have a small hole or two in the near side a little below the top. It just sits there. Nothing comes out of it. Nothing goes into it. So they should be removed, right?

Not so fast. In normal operation those holes are unused. But bathroom sink drains are notorious for being slow. Not blocked, because that’s obvious and gets fixed, but slow. And very often, when in the bathroom using the sink with the water running you’re doing something else. Brushing your teeth, shaving, removing makeup, or just distracted.

That’s when those holes come into play. As the drain runs slowly the water builds up in the sink. Eventually so much water builds up that it starts to run through those holes and down the drain. It’s not perfect, but it helps, and gives you a little more time to correct the problem. But if you never saw them used you might by a sink without them, then find a small lake in your bathroom.

The same thing can happen in code. You want to break long lines at a space if possible. As you’re going through the code you come across a strange byte-counting/examining loops. You’re confused because it doesn’t just start at column 80 and go backward looking for a ``. It starts at the beginning, checks values, skips spaces checks more, and keeps track of the last space it found. Very complicated. So you remove it and go with the simple solution.

You write your tests, deploy, and close out the task. Done and done. Then suddenly you start getting bug reports. Turns out you assumed that all of the input was simple ASCII code, but in reality it’s Unicode/MultiByte characters, so you can’t do the simple thing. Without enough context, you broke the code.

That’s Chesterton’s fence. So the next time you want to remove some seemingly unimportant code, make sure you know why it was added in the first place.

by Leon Rosenshein

Moving On

Today was my last day at Aurora. Some of you I’ve worked with for 15+ years across 3 ½ companies, others only for a few months at one company. Regardless, to all of you, a big thank you. You’ve all helped me learn and grow. As a developer, an architect, a mentor, and as a person.

Even though it’s been just over a year, I look back at all that’s been accomplished and it’s truly impressive. Aurora merged two companies’ people, technology, and infrastructure. It’s gone public. It’s pulling loads for partners. It’s showing the world that they can move the goods and manage the fleets.

Although I’m moving on, I have complete confidence that they will successfully bring not just the Aurora Driver, but the entire ecosystem, to market, safely, quickly, and broadly.

Thank you again, and I’ll miss you.

by Leon Rosenshein

Exit Criteria

Over my career I’ve written plenty of documents. Requirements docs, design docs, project specifications, white papers, and vision docs. They all have a few things in common. A definition of the current state, the problem with the current state, how the thing being written about will solve the problem (goals), and what issues it won’t address (non-goals). After that the different docs have different focuses and levels of detail appropriate for the role the doc was supposed to fill.

Over the weekend I ran across another section that should probably be in many of those docs. The exit criteria. Not the exit plan, which is a good idea, and says what you’ll do if/when you need to do something else. The exit criteria aren’t how you’ll change, it’s the set of questions/markers that tell you when to change.

Because one of the hardest things to do is to stop doing something that has been working well for a long time. After all, if it ain’t broke, don’t fix it. But what if it is broken, and you don’t recognize it, or don’t want to admit it? It’s also the sunk cost fallacy. It used to work. All I need to do is make one little tweak and all will be well. Besides, I built it, so it must be good.

This is especially true at the Process/Policy level. When I started at Uber there were 14 cultural values (14 is way too many, but that’s a separate issue). They worked really well for Uber at the beginning. They kept people working together, working quickly, and let the company grow much faster than outsiders expected. Then, over time, people started to use them not to make better decisions for the company, but to make themselves look better, sometimes at the expense of others. They took those values and used them to get what they wanted. Toe-Stepping and Be Yourself went from sharing diverse viewpoints to find the most effective to the loudest voice in the room wins. Let Builders Build went from don’t be blocked to promotion-based development. There are lots of other examples

But the values didn’t change. Instead, we started layering process on top of process to try and reduce the impact of weaponized values. Re-education and posters on the wall. An ever-changing promotion process. Locking the beer taps before 6:00 PM. Those things helped a little. Or at least helped reduce the expression of the problem, but they didn’t fix the problem. Eventually things got so bad that we got a new CEO and new values.

It’s by no means the only reason, but the fact that we didn’t revisit the values certainly contributed to the problem. And one of the big reasons they weren’t revisited was that everyone looked at the values themselves instead of the impact those values had. After all, who wouldn’t want to be themselves at work?

I don’t know exactly how to word it, but if, in the detailed description of each value it said something like “When this value starts being used to <XXX> we will reexamine ALL the values and ensure that they still represent and are being expressed as the values we want for Uber” things might have turned out a little differently.

This applies to documents, not just values. When you’re writing a design doc for a system you design it for a certain environment, with some allowed variation. Be explicit about that. If you’re designing a system to handle 100 QPS then it should probably be designed to handle 120-150 QPS just in case. And there should be a note in the doc that says “This design is no longer valid when QPS > 80 for longer than XX” so you know that you need to revisit the problem.

When you come across a system that is outside of its design parameters, make sure you understand how the current situation differs from them, and react accordingly

by Leon Rosenshein

Reading Roadmaps

Roadmaps are important. Having an idea about how to get where you"re going is pretty important to getting there. You know what’s more important than a roadmap though? A destination. Because if you don’t have a destination, you don’t know if your roadmap is going to get you to the right place. But even with a destination, you need to know how to read (or write) a roadmap.

Inevitably though, you end up presenting them to someone. When you do, or even (especially?) when someone presents one to you, remember Sam Higham’s advice:

  • This is a plan, not a promise
  • New ideas are still welcome
  • We don’t have all the answers
  • Not everything will work
  • We will update you as we learn more

There’s a lot to unpack there. Of course, there are the specifics. Things can (and will change). It won’t go exactly the way we think it will. No one has done exactly this before. If there is something that hasn’t been thought of, bring it up. We don’t know everything. We don’t even know all the questions to ask. We’re all learning and will continue to learn as we execute on the roadmap. The part that should be a promise though, is the promise to honestly provide updates as things progress.

Then there are the intangibles. It’s saying “Yes, we made a plan, but I"m not sure.” It’s an admission of imperfection. It’s an admission that we don’t know everything. It’s an admission we might be wrong. It’s a statement that we"re willing to change. As the person providing the roadmap it takes courage to make that kind of statement. And as the person who’s being shown the roadmap, it takes courage to accept the ambiguity and uncertainty inherent in it.

That’s why having a sea chart can be better than a roadmap. A sea chart embraces the uncertainty in the plan. You know where you are, you know what the known issues are, and you know where you expect to be along the way. Once you are on the way, you update the sea chart with your position and any other info discovered. Then you do some more planning, chart the best known course from where you are to where you want to be, and continue.

by Leon Rosenshein

Kinds of Costs

WIP

Costs are costs, right? You pays your money and you takes your choice. Simple, right? Not really. There are all kinds of costs. Up front, back end, hidden, and delayed for example. All of those are relevant to development. Besides those, there are two major ones to be aware of because they often turn into biases

  • Opportunity Cost: The time & money you spend on X means you can’t do Y. So choose wisely.
  • Sunk Cost: The time money already spent on X is gone. Is Y cheaper than continuing X?

Opportunity cost bias often gets expressed as one of 2 ways. The first is fear of making the wrong choice. Instead of thinking about what you should do and devoting enough resources on X to actually get it done, choose not to decide and peanut butter the resources around. You spread them thinly over multiple choices, and instead of finishing something you end up not finishing anything. Just like you want to [minimize work in progress] /posts/2021/09/09/). You have the time to get things done. You want to focus your resources.

The second is assuming facts not in evidence. Things like assuming you know exactly what the result of the different choices would be. That choice X will have a 100% return, while choice Y will have a 1000% return. It might happen, but what are the odds of each. You can’t use the potential upside without considering the probabilities. Not just ROI, but things like time, or how others will perceive it. You might assume X will take 2 days and Y 2 weeks, but that doesn’t mean it will happen. You might like bright colors and choose to paint a salmon-pink accent wall in your kitchen, but that doesn’t mean your prospective buyers will like it. There’s a reason why your real estate agent stages your house without doing anything unusual.

Sunk cost bias also come from fear. Fear that you’ve wasted your time/money/resources. No one wants to waste things, so you get that feeling you have that you’re almost done. That solving one more little problem will make everything work. After all, you’ve already invested (sunk) a bunch of resources into it. A little more to make it work makes sense. And if it’s a little more then you’re right. But if you let the fear (or pride of ownership) take control then you underestimate the cost of continuing and overestimate the cost of trying something new. Otherwise known as throwing good money after bad.

The thing is, both costs are real. You need to take them into account. The trick is to make a good decision. One based on facts, not biases.

by Leon Rosenshein

Cupid

In honor of Valentine’s Day, a new acronym. SOLID has been around for a while, and there are lots of good things about SOLID. Applying the SOLID principles (almost) always leads to better code. But, as @tastapod wrote, SOLID is about principles, and with principles, like rules, you’re either in compliance with the principles or not. Now you just have to decide how compliant you want to be. The answer to that of course, is it depends. Strict, absolute compliance can lead to over-abstracted code that might work well but is effectively opaque to someone new to the codebase. Ignoring SOLID can lead to a big ball of mud.

Enter CUPID. A set of properties for your code, not a set of rules to follow. The more your code exhibits these properties, the more readable, the more understandable, to another reader it is. So what is CUPID?

Composable: Each function/library/package has clear boundaries and works well with other functions/libraries/packages

Unix Philosophy: Do one thing and do it well

Predictable: Does what you expect. The principle of least surprise

Idiomatic: Feels natural. Don’t be too clever

Domain based: The solution domain models the problem domain in language and structure

CUPID is a set of properties that your code should have, not a set of principles to write it by. And the choice of those 5 properties was driven by a set of meta-properties. Each of the CUPID properties needed to be practical, human, and layered.

It’s those 3 meta-properties that really differentiate CUPID from SOLID. Instead of being about the code itself, CUPID is about how the code feels to the people who have to write, read, and maintain it. But don’t take my word for it. Read what Dan has to say about it when he introduced it.

Because, as Martin Fowler said,

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”

by Leon Rosenshein

More Perspective

​​I’ve talked about perspective before. Your point of view is a huge component of how you look at a situation. Let’s say you’re a fish. And let’s say you needed to navigate from Portland, Maine to Portland, Oregon. A map would be a good thing. It would really help you get from Portland to Portland. But for a fish the map wouldn’t look like most of the maps you’re used to seeing. It would look a lot more like this:

A map of the land as seen by a fish. Lots of water and only coastlines

Lots of ocean and a bit of coastline. (Yes, there’s too much land showing in Africa and major rivers aren’t shown, but you get the idea). Because that’s what’s important to fish. They don’t know, or care, what’s happening in Kansas or the central Asia. As far as they’re concerned those places might as well be on the moon. They have an impact on the world, but when getting from Portland to Portland they just don’t matter.

Working on software can be a lot like that. As the developer you care a lot about the internals. How the pieces fit together. How they communicate. How a change in one place impacts another. Your customers, on the other hand, couldn’t care less. If it’s an application they care about how many button clicks it takes them to do their task. If it’s a library they care about how good the documentation is and how consistent the API is. In general, customers want you to do the thing that makes their lives easier. The only time they care about making your life easier is when it helps them get what they want.

There are lots of ways that this impacts us, but one of the most important is how we communicate with our customers. When communicating with customers the key is to speak in their language. To talk about the benefits they get. How their life will be easier/better. Not that run time is ½ or that memory required is lower, but that they’ll be able to run twice as many things in the same time and it will cost them less. That’s customer benefit. Not “We’ve re-built the system as a set of microservices to reduce hard coupling”, but “Our new microservice architecture lets makes the system more resilient to network and hardware issues and lets us respond to customer needs faster”. Which one do you think customers want more?

So next time you need to explain something to someone and you draw a picture, make sure it’s from their perspective.

by Leon Rosenshein

Beware Of Just

This comes up in lots of different contexts

The problems with saying 'Just'

but it boils down to “I know you’re busy, but here’s a simple and obvious (according to my cocktail party understanding) solution to the problem I’m having. I need it working tomorrow.” 

After all, how hard can it be to write a script to automate it? You already know how to do it. Response times for your web query are slow. Just add a cache. It’s simple.

It’s simple on the surface, but when you dig into it there are a lot of details. Lots of fiddly bits that need to be just right, or you end up in worse shape than you were before. The first implementation of the script hides error messages, or worse, ignores errors and continues on, doing the wrong thing. The cache you just turned on gives inconsistent results depending on when you ask and where you ask from. All of these things are correctable, and when you get it working you are in better shape, but it’s not as simple as “Just cache it”.

I can be guilty of this myself. I used to say to people, "While you’re in there, can you make this other change?" While it might be the right time, it’s never as simple as that. Neither I, nor anyone else should expect it to be, yet we keep doing it.

So Just Remember, when you hear someone say “Just ….”, it’s never as easy as it sounds.