Recent Posts (page 33 / 65)

by Leon Rosenshein

Another 'Just No.'

Every year StackOverflow does a developer survey, and this year was no exception. Some of the questions they ask are about language, framework, library and platform usage. What gets used the most/least and what is liked the most/least. Like all surveys, some things make sense right away, some are of the "I wouldn't have thought that, but it makes sense", and others are of the "Huh???" category. The one in the last category that always makes me go WAT is Rust. Is #19 in the list of most used languages, but #1 in the most loved, and 20% higher than #2. How can so many people love a language they don't use?

But still, that's just data. It's not information, let alone knowledge or wisdom. And some people have tried to turn that data into wisdom, such as this Medium article.

According to that article, we should all be learning and using Julia, since it's the language people are most satisfied with. We don't know what they're doing with it, but they're satisfied, and who doesn't want job satisfaction?

Alternatively, you could pick your language of choice based on popularity and paycheck. You know, what all the cool cats and kittens are using. In that case, C, Java, and Javascript should be your choice. It certainly makes it more likely that you'll be able to use the Clone pattern from yesterday's list, but it doesn't say much about the quality of the result.

Or, put it all together and let the wisdom of the masses guide you. By this analysis the most well rounded choice, in terms of community size, salary, and satisfaction are the big shell languages, Bash, Shell, and Powershell. I can just imagine a self driving vehicle built using Powershell. I can imagine it, but I don't think I want to ride in it.

The right answer to which language to use is, as with most things software, it depends. Here's some wisdom for you. Instead of bringing your favorite language to the problem space, look at the problem space first. See what's being done. See what the pros and cons in the space are. Remember, you're trying to solve a problem in a problem space, not trying to use a language. The language (and it's ecosystem, including community, libraries, and toolset) is just a tool you use to solve the problem. It's not a solution you carry with you and then apply to whatever problem you come across.


by Leon Rosenshein

Real World Patterns

You've probably heard of the Gang Of Four's Design Patterns, and I've talked about some of them already. There's some really good ideas in that book, and like all things architectural, using the right pattern at the right time makes things easier in the future. Get it wrong and not so much.

Probably the most common mistake I've seen with those patterns is overapplication. People learn a pattern and then apply it everywhere. I've done it. For me the singleton was the worst. When I first saw that I *knew* that it was what I had been looking for. Singletons started popping up in my code everywhere. Inside classes. Across classes. It wasn't until I ran into the Special Order pattern of singleton creation that I realized I had gone too far.

There are plenty of other lists of patterns out there. Below is a list that I think has a lot of connection to code as seen in the wild. I have to admit that I've been known to use the Clone pattern a few times, and Retroactive Formalization is definitely the best way to make sure you meet the design requirements AND have the docs match the code, at least for a while. What other real-world patterns have you seen?



by Leon Rosenshein

Don't Cross The Streams

Domain driven design is all about bounded contexts. I like bounded contexts. They help you know what something is responsible for, and by extension, what it's not (that would be everything else). Having those boundaries (not crossing the streams) makes it easier to keep things straight and reduces cognitive load.

On the other hand, having all those different domains is adding complexity, Especially if those domains are each different services with some kind of RPC interface. In that case you not only have multiple domains to keep track of, but you could do everything correct and the RPC could fail because of a fiber seeking backhoe, so you need to be able to handle that case. And that increases cognitive load too.

Like everything else in software, when to keep things separate and when to bring them together depends on context. Remember, we're not here to build the perfect thing, we're here to add value to the customer. Value today is better than undelivered perfection.

It's a balance, and the right place for the boundary will change over time. How often things change can move the boundary. The more something changes the more important it is to make it easy to change without impacting others. How many other people/teams/programs need to use the context can as well. If there are 100 use cases then having a single version is very important. If there's only one use then it's already used in every case.

There are sometimes good reasons to cross the streams (mix your domains). One of the most common is time. And that can be OK. As long as you document why you're choosing a short term gain over long term stability and what the criteria are that will tell you when you need to fix it. For example, you might mitigate an outage by crossing a domain barrier in a client rather than make a change to a few domains, because you need to fix it now. But once things are working and you have the time, go back and clean up the boundaries so everyone gets the benefits.

by Leon Rosenshein

Experience

Some say that experience is the best teacher. And baring learning styles, there's a lot of truth to that saying. And not just learning by doing. Learning from your mistakes. And even better than that, learning from other's mistakes.

But the real key to experiential learning is not the doing of the thing, it's the reflection afterward. In school you might call it the lab report or case study, and at work we call them tech sharing or incident reports, but regardless of the name, the goal is to identify the parts that made a difference and why so that they can be incorporated into our internal understanding of the world. We can then use that understanding to inform future decisions.

Because if you don't reflect on what happened and why, you're not really learning, you're just setting up a conditioned response. The next time something happens that is similar enough to trigger your filter you'll make the same response. Of course the situation is not the same, It might be close, but if nothing else time has passed. And if the trigger is close enough the same response will probably work. Thus reinforcing your "learning"

Which brings us to the story of the 5 monkeys. You know, the one with the ladder to a banana on a string. If you don't know it, the short version is that a group of monkeys learn that climbing the ladder brings on group punishment. Once they've all really learned that the monkeys are slowly replaced. Each new monkey learns that climbing the ladder gets them punished by the other monkeys. Eventually non of the monkeys have ever experienced the punishment, but they continue to train new monkeys in the group to not climb the ladder. While the story is mostly apocryphal, there's still a lesson to be learned.

Learn from your experiences, but reflect upon them and understand what the learnings really are. As we go forward come to inflection points where a small change can have a large impact. We're approaching such a point, so let's make sure that our decisions now are based on the learnings from our experiences, not just "that's the way we've always done it here."

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.