<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Randall Koutnik</title>
    <description>The latest articles on DEV Community by Randall Koutnik (@rkoutnik).</description>
    <link>https://dev.to/rkoutnik</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F35555%2F330c282d-c20b-4d0f-bdad-af762b79e7e6.jpg</url>
      <title>DEV Community: Randall Koutnik</title>
      <link>https://dev.to/rkoutnik</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rkoutnik"/>
    <language>en</language>
    <item>
      <title>The Corporate Culture Gap</title>
      <dc:creator>Randall Koutnik</dc:creator>
      <pubDate>Sun, 03 May 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/rkoutnik/the-corporate-culture-gap-5ej2</link>
      <guid>https://dev.to/rkoutnik/the-corporate-culture-gap-5ej2</guid>
      <description>&lt;p&gt;I was involved in a recent chat conversation around the concept of “Culture Buddies.” The idea is to help onboard new employees by having a current employee assigned to them with the specific task of helping the new employee acclimate to the company’s culture.&lt;/p&gt;

&lt;p&gt;I had a direct and immediate dislike of the idea.&lt;/p&gt;

&lt;p&gt;(Note: this is different from finding a trusted friend at a company to help you navigate the sticky parts - something I strongly recommend).&lt;/p&gt;

&lt;p&gt;The fact is, virtually every software company has a significant gap between culture-as-imagined and culture-as-practiced. For example, many companies claim to “hire the best” but still pay below-market. However, pointing out this contradiction is not a great way to further your career.&lt;/p&gt;

&lt;p&gt;Now let’s imagine a corporate Culture Buddies program. The type of person who’d be selected to be a “Culture Buddy” is likely someone who will present culture-as-imagined even when it does not line up with culture-as-practiced. The company wants to present culture-as-imagined to new hires. When I start a new job, I’m looking for the opposite - I want to know what the exceptions to the stated culture are so I don’t end up running face-first into them (which I’ve done many times in my career).&lt;/p&gt;

&lt;p&gt;Often the difference between culture-as-imagined (CAI) and culture-as-practiced (CAP) isn’t visible to those higher up, as those lower down smooth over issues to preserve the image.If your company has a significant gap between CAI and CAP, then a buddy system designed by those very same higher-ups won’t help you. You have bigger problems. Oh, and your company definitely has a significant gap. Basically everyone does.&lt;/p&gt;

&lt;p&gt;So what should we do?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Corporate Culture Gap
&lt;/h2&gt;

&lt;p&gt;A company needs a goal. Without a goal, you can’t have alignment - there isn’t anything to align towards. Without alignment, you can’t build trust, and without trust, you’re lost in a hopeless maze of micromanaging.&lt;/p&gt;

&lt;p&gt;So you need a goal. What makes for a good goal is a bit out of the scope of this discussion. As the leader of a company, you need to:Make sure everyone knows the goal of the company (so repeat it whenever you can!)Make sure everyone knows their part of the goal&lt;/p&gt;

&lt;p&gt;The most egregious splits between CAI and CAP I’ve seen were because there was a stated goal (or worse, multiple stated goals) and it was abundantly clear to those paying attention that the actions of the company (and the orgs within the company) were not in alignment with the goal. This is called the Corporate Culture Gap. Speaking up about actions not being aligned with stated goals results in being labeled “not a culture fit”. This label does significant harm to your career, and can often result in termination.&lt;/p&gt;

&lt;p&gt;Some people just don’t care about the culture gap. They just go into work, move some tickets from left to right, and go home. Others are culture cheerleaders. They focus just on CAI and ignore/justify the difference. Some people just want to be a follower (and that’s ok!). Finally, there are people who care deeply about key pieces of culture-as-imagined. Most likely, the gap impacts them directly. (CAI: “We Value Diversity”, CAP: “We Underpay Everyone Who’s Not A White Dude”). For the group that cares deeply, there are those that speak up, and those that pretend to be cheerleaders. In any company with a non-trivial gap, those that speak up are not appreciated. Those that pretend can end up being effective, if miserable.&lt;/p&gt;

&lt;p&gt;To put it simply, the cruel irony of company culture is that you can only speak up to say “This is a psychologically unsafe environment” in a safe environment.&lt;/p&gt;

&lt;p&gt;So, I started this section by talking about goals. What’s the goal of our culture buddy program?&lt;/p&gt;

&lt;p&gt;As a new employee, my goal is to learn as much about CAP as possible so that I can be effective within the system. I won’t trust a buddy given to me by the company, because I’m looking to find the parts of the company’s culture that it can’t (or won’t) see.&lt;/p&gt;

&lt;h2&gt;
  
  
  Small Gaps
&lt;/h2&gt;

&lt;p&gt;If there isn’t a significant culture gap, then that’s awesome! Any engineer who’s had a few jobs has been burned by this gap enough that they’ll need some really solid proof that the company means what it says. Personally, I’ll write off anyone assigned as a cheerleader.&lt;/p&gt;

&lt;p&gt;In this small-gap case, new employees take some time to adjust, but get there eventually. This happened to pretty much everyone who joined Netflix. There’d be an initial period where they’d be thinking “you don’t actually mean you let engineers do what they want” but as newcomers tested and experimented, they’d realize that yes, for the most part, Netflix lived up to its culture. (Was there a gap? Certainly. But it’s the smallest gap I’ve seen and management was open about times when the culture failed.)&lt;/p&gt;

&lt;p&gt;So in the small-gap case, from management’s perspective, a culture buddy may help things along and get the new employee adjusted a bit faster. Though not that much faster, because in the small-gap case, everyone’s living the culture anyway so a specific person may not be that helpful.&lt;/p&gt;

&lt;p&gt;In the large-gap case, on the other hand…&lt;/p&gt;

&lt;h2&gt;
  
  
  Large Gaps
&lt;/h2&gt;

&lt;p&gt;If you’re a manager at a large-gap company and are aware of (and dislike) the gap, then the goal is to build a small-gap team. An onboarding buddy will be enormously helpful here to help the new employee guide the rough waters that would result in the cultural mismatch between a small-gap, goal-driven team and the wider, large-gap company. However, this’d be a pretty high-touch situation, for obvious reasons.&lt;/p&gt;

&lt;p&gt;If you’re a manager/leader at a large-gap company and either unaware of the gap (or aware and don’t care, which is the same thing), then the purpose of a culture buddy system is a little more vague. I find it a bit more difficult to write about this situation without just getting all cynical everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Example Gap
&lt;/h2&gt;

&lt;p&gt;Let’s look at a specific example to illustrate the difference between Culture As Imagined and Culture As Practiced: Feedback.&lt;/p&gt;

&lt;p&gt;Culture-as-imagined (CAI), every company ever says that feedback is important. Feedback becomes a Key Cultural Value, companies offer classes on effective feedback, managers talk about how valuable feedback was to them, etc, etc. This looks great until someone actually gives constructive feedback. Suddenly, the culture gap becomes very visible.&lt;/p&gt;

&lt;p&gt;Some managers treat feedback as confusion, and instead of responding to the feedback, they keep on explaining, as if it was abundantly clear how they were right. Feedback was something tossed into a void. In this case, employees learn to shut up and nod. Worse, these managers think they’re doing a great job! After all, if they were doing a bad job, someone would say something. Other managers start screaming fits whenever they’re questioned. Heck, one place I worked, all feedback was just straight-up ignored.&lt;/p&gt;

&lt;p&gt;Early on in my career, I would run into this cultural mismatch right off the bat. I’d see something that could be improved and give feedback - just like the culture docs said! At best it would fall by the wayside and I’d discover that the company wasn’t really interested in my feedback. At worst, I’d endure a public berating in front of all of my new teammates. Either way, I burned a lot of social capital because I followed the company’s stated values.&lt;/p&gt;

&lt;p&gt;I can’t say I always gave feedback well - this is something I’ve improved a lot over the years, with a long way to go - but the companies set new employees up to fail. This might even be the catalyst for a culture buddy system! “Hey, new folks end up with a rough start, maybe we could help them out.” Good intentions, but the problem here isn’t the onboarding, the problem is you’re lying to your employees. Fix that, and the onboarding problem gets fixed too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Any leader who wants to be a good leader (and not just “in charge”) needs to keep the corporate culture gap in mind through all of their decisions, large and small. Adding a “culture buddies” program is just a band-aid on a much larger problem. The best companies out there recognize the key to a smooth onboarding isn’t further indoctrination but building trust by being open and honest internally about how the corporate culture works in practice.&lt;/p&gt;

&lt;p&gt;Thoughts? I’d love to hear them. You can reach me at &lt;a href="//mailto:blog@rkoutnik.com"&gt;blog@rkoutnik.com&lt;/a&gt; or in shorter form at &lt;a href="https://twitter.com/rkoutnik"&gt;https://twitter.com/rkoutnik&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Why is TypeScript so great?</title>
      <dc:creator>Randall Koutnik</dc:creator>
      <pubDate>Mon, 24 Sep 2018 00:00:00 +0000</pubDate>
      <link>https://dev.to/rkoutnik/why-is-typescript-so-great-17am</link>
      <guid>https://dev.to/rkoutnik/why-is-typescript-so-great-17am</guid>
      <description>&lt;p&gt;In my developer career, I don’t think I’ve met anything as revolutionary as &lt;a href="https://www.typescriptlang.org/"&gt;TypeScript&lt;/a&gt;. There are plenty of shoulders TypeScript is standing on (everyone who worked to get JS devs to accept build systems!) but TypeScript is a brilliant cumulation of that work that’s fundamentally changed how I do my job. So much so, that I finally switched off my beloved Sublime Text to Visual Studio Code for better TypeScript support.&lt;/p&gt;

&lt;p&gt;(As an aside, the fact that I’m using a Microsoft editor to write a Microsoft language and that both are open source still feels weird)&lt;/p&gt;

&lt;p&gt;For those of you new to frontend development (or those who are returning after a long hiatus), TypeScript is a new language that’s a superset of JavaScript that adds optional types into the mix. Here’s a snippet of TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let currentUserId = 7;
let users = [{
  id: 7,
  firstName: 'Robert',
  lastName: 'Smith'
}, {
  id: 12,
  firstName: 'Dana',
  lastName: 'Jones'
}];

let currentUser = users.filter(u =&amp;gt; u.id === currentUserId);

console.log('Hello,', currentUser.firstName, '!');

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most importantly, you’ll notice that there aren’t any type annotations or other funky business in this snippet. &lt;em&gt;All JavaScript is also valid TypeScript&lt;/em&gt;. This is TypeScript’s greatest asset. All you need to do to convert a codebase to TypeScript is a single command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;find . -name "*.js" -exec bash -c 'mv "$1" "${1%.js}".ts' - '{}' \;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(ok, ok, so there’s more to it than that. We’ll get to that later).&lt;/p&gt;

&lt;p&gt;So all your JavaScript is valid TypeScript. So what? The answer lies in just how dang &lt;em&gt;smart&lt;/em&gt; TypeScript is. It’s not just “We jammed a bunch of types into JavaScript”, but an entire ecosystem of tooling around that, all built with the developer in mind. It took some time to get where we are today (I gave up on TypeScript several times in the dark days of &lt;code&gt;v0.x&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;TypeScript takes a look at the above snippet and knows that &lt;code&gt;users&lt;/code&gt; is an array of objects and &lt;code&gt;filter&lt;/code&gt; is a method on an array that returns another array. Therefore, &lt;code&gt;currentUser&lt;/code&gt; is an array and …wait a minute! Arrays don’t have a &lt;code&gt;firstName&lt;/code&gt; property! TypeScript then slams a red squiggle underneath this glaring issue, allowing you to fix it right in the editor itself. No need to content switch to the browser, stare at a bizarre &lt;code&gt;undefined&lt;/code&gt; that shouldn’t be there, and eventually track it down to a &lt;code&gt;filter&lt;/code&gt; that should be a &lt;code&gt;find&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Before TypeScript, I made these kinds of mistakes all the time and caught &lt;em&gt;most&lt;/em&gt; of them before they got to production. Now I still make these sorts of mistakes all the time but they’re caught immediately instead of creating incredibly quirky bugs.&lt;/p&gt;

&lt;p&gt;TypeScript changed the game even without needing to modify our code at all. Even at the start, it’s a super-linter that allows us to offload an enormous amount of working memory about our codebase and JavaScript to a tool, allowing us to spend those brain cells on a better architecture and writing mushy love letters masquerading as blog posts about said tools.&lt;/p&gt;

&lt;p&gt;TypeScript is incredibly powerful as a super-linter and would be just fine if that’s all it did. Next time we’ll talk about types, how to define them in TypeScript, and just why that’s useful.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Stateful Filters in RxJS</title>
      <dc:creator>Randall Koutnik</dc:creator>
      <pubDate>Mon, 17 Sep 2018 00:00:00 +0000</pubDate>
      <link>https://dev.to/rkoutnik/stateful-filters-in-rxjs-3182</link>
      <guid>https://dev.to/rkoutnik/stateful-filters-in-rxjs-3182</guid>
      <description>&lt;p&gt;I’m just finishing the last stages of writing &lt;a href="https://pragprog.com/book/rkrxjs/build-reactive-websites-with-rxjs"&gt;Building Reactive Websites with RxJS&lt;/a&gt;, to be published through Pragmatic Publishing. I’m a huge fan of RxJS, even if it is a bit complicated to get used to. In an effort to demystify this library, I’d like to walk through a few case studies over the next few weeks and analyze how to use it in real-world scenarios.&lt;/p&gt;

&lt;p&gt;The first case study comes from one of my old jobs at a cybersecurity company. This company had an offering where they’d crawl The Dark Web (I still can’t belive sales folks said that with a straight face) and look for keywords set up by clients. Ostensibly, this tool could be used to detect leaks of software and/or internal documents. In order to achieve this scanning ability, we need to build a filter that can be dynamically updated.&lt;/p&gt;

&lt;p&gt;The crucial thing to think about when writing software using RxJS is to model everything as a stream of events over time. If your application does not lend itself well to this modeling, RxJS may not be for you. Fortunately, this task is easy to model as two separate streams. One, from Kafka, is new data from the crawler. The other comes from a database poller and contains the keywords our filter needs to test against.&lt;/p&gt;

&lt;p&gt;We’ll start off with two magic variables that represent these streams, as dealing with Kafka is outside the scope of this post. Appending a dollar sign to the end of the variable is a convention used to show that variable is an observable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;crawlResults$;
latestKeywords$;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;RxJS already has a built-in filter operator, so this would work, at least until the list of keywords was updated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;crawlResults$
.pipe(
  filter(content =&amp;gt; keywords.some(content.includes(keyword))
)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tricky part of this challenge is that we’re implementing a &lt;em&gt;stateful&lt;/em&gt; filter. Clients could update the keyword list at any time. We’ll need to store that state somewhere. One option is to just create an array of keywords and manually keep it updated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let filterKeywords = [];
// every five minutes
interval(5 * 60 * 1000)
.pipe(
  mergeMap(() =&amp;gt; dbQuery())
)
.subscribe(newFilterKeywords =&amp;gt; {
  filterKeywords = newFilterKeywords;
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This leaves us holding the bag around both state and managing subscriptions. In this example, we need to make sure that the subscription is properly disposed of, otherwise we might accidentally create tons of pollers and overwhelm the database with queries (this never happened, I don’t know what you’re talking about and don’t belive anything my former coworkers say about this).&lt;/p&gt;

&lt;p&gt;The obvious advantage of RxJS is modeling everything as streams but a lesser-known advantage is that RxJS provides many ways to store state inside the framework, ensuring that the library worries about subscriptions and filtering. Combining two streams together in RxJS is known as ‘merging’ and there’s a variety of merge operators to utilize here. Most merges don’t maintain an internal state and just send data on when they get it. Here, we want to know the latest value from both streams on every event, so we turn to &lt;code&gt;combineLatest&lt;/code&gt;. The &lt;code&gt;combineLatest&lt;/code&gt; constructor tracks multiple streams and on an event from any stream, emits the latest value of all streams as an array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;combineLatest(
  crawlResults$,
  latestKeywords$
)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’re almost there. The one remaining problem is that whenever &lt;code&gt;latestKeywords$&lt;/code&gt; updates, this might pass along the latest hit from the crawler as well. There’s one operator that’ll save us: &lt;code&gt;distinctUntilChanged&lt;/code&gt;, which is a stateful filter that only passes a value if it’s different from the previous value. Throw in a &lt;code&gt;map&lt;/code&gt; to extract the results from the keywords, and this looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;combineLatest(
  crawlResults$,
  latestKeywords$
)
.pipe(
  filter(([results, keywords]) =&amp;gt;
    keywords.some(results.includes(keyword))),
  map(([results, keywords]) =&amp;gt; results),
  distinctUntilChanged()
);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tada! A stateful merge filter, with the heavy lifting offloaded to the RxJS library. If you want to learn more about RxJS, including building many functional examples, check out &lt;a href="https://pragprog.com/book/rkrxjs/build-reactive-websites-with-rxjs"&gt;Building Reactive Websites with RxJS&lt;/a&gt;, now in beta.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Incentivize Teams, not People</title>
      <dc:creator>Randall Koutnik</dc:creator>
      <pubDate>Sat, 17 Mar 2018 19:51:00 +0000</pubDate>
      <link>https://dev.to/rkoutnik/incentivize-teams-not-people-2k31</link>
      <guid>https://dev.to/rkoutnik/incentivize-teams-not-people-2k31</guid>
      <description>&lt;p&gt;Any programmer worth their salt is willing to help team members out when they’re in a pinch. Software development is a team sport, after all. Unfortunately, management can often completely miss the point and create perverse incentives that wreck a team’s cooperation and communication. If you’re a software manager, here’s a quick self test:&lt;/p&gt;

&lt;p&gt;Put together a list of all of your incentives, from compensation increases &amp;amp; promotion to “Who gets the new project”. Make sure to include things like a regular team lunch or a “Employee of the Month”. Now, go through that list and ask yourself the following question for each item:&lt;/p&gt;

&lt;p&gt;“If Bob goes over to Alice and says ‘Do you have a minute? I need help with something.’, does this incentive move Alice towards helping Bob?”&lt;/p&gt;

&lt;p&gt;Let’s go through some common management antipatterns and what impact they have on Alice’s answer.&lt;/p&gt;

&lt;p&gt;The worst of the worst are programs that link cash or other bonuses to individual performance goals. Tying individual performance to comp means that the better financial decision for Alice is to make an excuse and focus on her own work metrics instead. Bob’s unhappy because he’s still blocked. Alice is also unhappy because she has to choose between focusing on her work or falling behind on her performance goals. Do you really think more cash will increase morale enough offset this massive break in teamwork?&lt;/p&gt;

&lt;p&gt;On the other hand, some bonus programs reward engineers with bonuses that are dependent on &lt;em&gt;company&lt;/em&gt; performance (the biggest team there is!). Alice earns more if the entire company does well, rather than focusing exclusively on Alice’s own objectives. Now Alice’s extrinsic and intrinsic incentives are aligned. She can help Bob, safe in the knowledge that the company wants them both to succeed.&lt;/p&gt;

&lt;p&gt;Some companies (like my employer, Netflix) go a step further and do away with bonuses entirely, providing top-of-market pay instead, coupled with explicit trust in the employee to do what’s best for the company in any given situation. Netflix’s expense policy, “Act in Netflix’s best interests”, is the archetypical example.&lt;/p&gt;

&lt;p&gt;Promotions can be another sticking point. If there’s an open req for a higher-level position that both Bob and Alice are hoping to get, they’re stuck in the same quandry. &lt;a href="https://mtlynch.io/why-i-quit-google/"&gt;Google is infamous for only looking at feature development&lt;/a&gt; when making promotion decisions and leaving everything (and everyone) else to the wayside. Unsurprisingly, this means they’re launching &lt;em&gt;another&lt;/em&gt; chat app while letting Google Reader die.&lt;/p&gt;

&lt;p&gt;It may not be as direct as helping a coworker synchronously. There are many other ways engineers work for the betterment of the team/org/company: writing documentation, providing product feedback, sitting in for UX testing, giving internal talks, and more. One option is to sit down and create individual performance metrics for all of these activities. The better option is to remove perverse incentives and let the team do what they do best: build great products.&lt;/p&gt;

&lt;p&gt;(Your interview process is filtering out the &lt;a href="http://www.brendangregg.com/blog/2017-11-13/brilliant-jerks.html"&gt;brilliant jerks&lt;/a&gt;, right?)&lt;/p&gt;

</description>
      <category>leadership</category>
    </item>
    <item>
      <title>The git's guide to git: Commits &amp; their messages</title>
      <dc:creator>Randall Koutnik</dc:creator>
      <pubDate>Sat, 16 Jul 2016 00:00:00 +0000</pubDate>
      <link>https://dev.to/rkoutnik/the-gits-guide-to-git-commits--their-messages-37hm</link>
      <guid>https://dev.to/rkoutnik/the-gits-guide-to-git-commits--their-messages-37hm</guid>
      <description>&lt;p&gt;The core unit of git is the commit. A commit is simple on the surface (some code changes and a message). Such simplicity belies the complexity within.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to commit
&lt;/h2&gt;

&lt;p&gt;I’ve heard many opinions on when one should commit from “commit early, commit often” to “one commit per release” (yikes).The only method I’ve found that consistently reduces developer headaches is to make one commit per change.This requires some discipline to break up small changes into their own commits and squashing multiple commits that all accomplish parts of the same change. “Change” itself is subjective, my rule of thumb being “The smallest edit to the code that can be considered complete”. Half a refactor might be able to run &amp;amp; pass tests but it’s not ‘complete’.&lt;/p&gt;

&lt;p&gt;Making one commit per change supercharges tools like &lt;a href="///articles/The-gits-guide-to-git-Bisect.html"&gt;&lt;code&gt;git bisect&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://git-scm.com/docs/git-revert"&gt;&lt;code&gt;git revert&lt;/code&gt;&lt;/a&gt;. As tempting as it is to integrate several small changes in a single commit, you’ll be much happier with multiple commits if one of those changes need to be reverted later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commit messages
&lt;/h2&gt;

&lt;p&gt;Technically speaking, commit messages aren’t that exciting. There are two ways to write ‘em. If you run &lt;code&gt;git commit&lt;/code&gt;, git will helpfully open an editor to write the commit message. (Unhelpfully the editor is always Vim, git is credited with being the only reason developers know how to exit Vim [0]). On the other hand, you can add the &lt;code&gt;-m&lt;/code&gt; flag to add an inline commit message: &lt;code&gt;git commit -m 'my commit'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On the other hand, if you’re &lt;em&gt;not&lt;/em&gt; a mythical 10x programmer, you work on a team with other people. (if you are, &lt;a href="///2016/04/29/Wanted-Ninja-Rockstar-Code-Monkey-Hacker-Unicorn.html"&gt;we could use a fellow like you&lt;/a&gt;). Even if you &lt;em&gt;are&lt;/em&gt; flying solo, you’re on a team comprised of now you, one-month-ago you, two-month-ago, etc. We all need some trail of breadcrumbs to follow whatever insane trail of logic February us was thinking.&lt;/p&gt;

&lt;p&gt;Which is why commit messages like this really tick me off:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit 32f4410abb2a901016c4a8b23c4b487e36be9916
Author: Randall Koutnik &amp;lt;souper_leet_h4x0r@rkoutnik.com&amp;gt;
Date: Tue Jun 14 15:05:51 2016 -0700

    Fix error on alert page
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;What was this guy thinking?&lt;/em&gt; Seriously, what was he thinking? I need to know the motivation for this commit - why, of all possible uses for his time, did this coder decide to make this one?&lt;/p&gt;

&lt;h3&gt;
  
  
  Context is king
&lt;/h3&gt;

&lt;p&gt;When I was in college, I took Calc 2 and passed by a single point. I am not good with advanced math. As I was cramming for the Calculus final, searching the textbook for any hint of explanation that would impart an understanding of antiderivatives, I came across the most terrifying sentence ever written:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The explanation for such a phenomenon is so trivial it is left as an exercise for the reader&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I hadn’t exercised in three days, so I went for a run. This didn’t help my understanding of integration by parts at all. The author of the textbook is well-read in calculus, as he literally wrote the book on it. He had a much greater context for calculus than I did and assumed I’d be able to pick up the finer points.&lt;/p&gt;

&lt;p&gt;The author of the commit message above knows what bug was fixed. Their issue is in assuming the reader has the same context.&lt;/p&gt;

&lt;h3&gt;
  
  
  The three questions
&lt;/h3&gt;

&lt;p&gt;Commit messages need to answer three questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What changed?&lt;/li&gt;
&lt;li&gt;How was the change implemented?&lt;/li&gt;
&lt;li&gt;Why was that change nessecary?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The commit above only answers “what” (and poorly at that). We’re still left wondering &lt;em&gt;which error?&lt;/em&gt; Any code that’s existed for 90 seconds has multiple errors. If I know that a fix when cloning alerts that had an ampersand in the name introduced a regression and am combing through the history trying to find said commit, this message is near-useless.&lt;/p&gt;

&lt;p&gt;This message also doesn’t provide a high level “how” of the fix. Was the answer better parsing? A less-restrictive regex? Skipping all the relevant unit tests? Answering “how” in the commit message saves the reader the effort of reading through the diff.&lt;/p&gt;

&lt;p&gt;Finally, and most importantly, &lt;em&gt;why&lt;/em&gt;? Fixing errors is important, sure. Why this error? Most modern git systems allow linking to an issue tracker; apply links liberally. Some, like GitHub, allow you to close an issue with a commit message containing &lt;code&gt;Fixes #1234&lt;/code&gt;. Two birds with one stone!&lt;/p&gt;

&lt;h3&gt;
  
  
  A better commit
&lt;/h3&gt;

&lt;p&gt;Let’s take a swing at fixing up the commit above. Using our new heuristics for message quality, we need to add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Why&lt;/em&gt; the commit happened (through some external links)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;How&lt;/em&gt; the change works&lt;/li&gt;
&lt;li&gt;More details in the summary
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit 32f4410abb2a901016c4a8b23c4b487e36be9916
Author: Randall Koutnik &amp;lt;souper_leet_h4x0r@rkoutnik.com&amp;gt;
Date: Tue Jun 14 15:05:51 2016 -0700

    Fix name parse bug when cloning alert with a '&amp;amp;' in the name

    Previously, the API would choke because we weren't escaping '&amp;amp;' in alert names on cloning.
    Now the clone service escapes the name before the API call.

    Fixes #1337
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now have a neat little summary, an explanation of the actual fix and a connection to external details. Now if (horrifyingly) some part of the system relied on unescaped data, we’d know exactly what commit to start with when the regression tickets come piling in…&lt;/p&gt;

&lt;p&gt;[0] Seriously, you can set the editor git uses either through &lt;code&gt;git config --global core.editor "your-editor-here"&lt;/code&gt; or the environment variable &lt;code&gt;GIT_EDITOR&lt;/code&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Wanted: Ninja Rockstar Code Monkey Hacker Unicorn</title>
      <dc:creator>Randall Koutnik</dc:creator>
      <pubDate>Fri, 29 Apr 2016 00:00:00 +0000</pubDate>
      <link>https://dev.to/rkoutnik/wanted-ninja-rockstar-code-monkey-hacker-unicorn-3nnl</link>
      <guid>https://dev.to/rkoutnik/wanted-ninja-rockstar-code-monkey-hacker-unicorn-3nnl</guid>
      <description>&lt;p&gt;We’re looking for the best of the best - but as you can already tell from the title, we have no idea what that looks like. We want someone experienced enough to implement our ridiculous ideas but paradoxically &lt;em&gt;lacking&lt;/em&gt; the experience to realize what a raw deal we’re offering. Work long hours to &lt;a href="https://rkoutnik.com/2016/04/21/implementers-solvers-and-finders.html"&gt;implement vague ideas with no autonomy&lt;/a&gt; for &lt;a href="https://rkoutnik.com/articles/The-Myth-of-Equity-as-Motivation.html"&gt;vague promises of getting rich one day&lt;/a&gt;. After all, money’s the only thing that motivates anyone, right? Coding isn’t a creative field, it’s just telling the computer what to do.&lt;/p&gt;

&lt;p&gt;You’ll get to work with all of our C-levels as they order you around on a daily basis. We’re an “Agile” team, so long as that means cutting corners to meet sales deadlines. We practice HN-driven-development. Plan on working ~100+ hours a week during sprints. If that scares you, don’t apply. We don’t want people who are scared by silly things like reality.&lt;/p&gt;

&lt;p&gt;Get in on the ground floor to a catastrophe that’s sure to hit the front page of TechCrunch!&lt;/p&gt;

&lt;p&gt;Must haves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;White&lt;/li&gt;
&lt;li&gt;Male&lt;/li&gt;
&lt;li&gt;Unshakable confidence due to the &lt;a href="https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect"&gt;Dunning-Kruger effect&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;No interest in a life outside of the company&lt;/li&gt;
&lt;li&gt;5 years of experience in a three-year-old technology&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nice to haves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enough knowledge to convince a non-technical person you’re an expert in a handful of bleeding-edge technologies&lt;/li&gt;
&lt;li&gt;Sneering disdain for the proven tech you should be building with&lt;/li&gt;
&lt;li&gt;A GitHub profile that shows you’re already willing to work for free in your off hours&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Perks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Yes you’ll get all the usual benefits, but if you’re really going for perks, Google is your best bet! If you want to make an impact, then please apply.&lt;/li&gt;
&lt;li&gt;401k? Hah, you won’t need that with how rich your sliver of equity will make you!&lt;/li&gt;
&lt;li&gt;We’ll have a large variety of alcohol in the office as well as an assortment of video games for the perfect frat environment&lt;/li&gt;
&lt;li&gt;Office located in trendy downtown district in order to burn VC cash faster&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Salary: Something that we’ll claim is top-of-market but is well below. We’ll offer the low end of the range, citing lack of experience with some framework that hasn’t left beta.&lt;/p&gt;

&lt;p&gt;Equity: 0.1% - 2% for the "right person".&lt;/p&gt;

</description>
      <category>career</category>
    </item>
    <item>
      <title>Implementers, Solvers, and Finders</title>
      <dc:creator>Randall Koutnik</dc:creator>
      <pubDate>Thu, 21 Apr 2016 00:00:00 +0000</pubDate>
      <link>https://dev.to/rkoutnik/implementers-solvers-and-finders-3f7a</link>
      <guid>https://dev.to/rkoutnik/implementers-solvers-and-finders-3f7a</guid>
      <description>&lt;p&gt;I was talking to a former student when he brought up &lt;a href="http://thecodist.com/article/my-biggest-regret-as-a-programmer"&gt;an article written by a well-seasoned programmer regretting his choice of career&lt;/a&gt;. This fellow had rejected the management path in order to stay in the coding trenches and as a result, ended up in some absolutely crummy situations. He writes about management antipattern after antipattern that left him sitting with the bill.&lt;/p&gt;

&lt;p&gt;Hearing about a dismal career like that is depressing. So much so, that my student who previously was one of my most enthusiastic programmers had turned morose. Who’d blame him? All he had to look forward to was a life filled with misery caused by other folks’ poor decision-making skills. Learning that sub-par managers will dictate your whole life is almost as traumatizing as dealing with said managers. To make matters worse, his team had recently mulled over their future career plans at lunch. None of them anticipated that they’d remain programmers. As soon as they could, they were going to take the leap into management, avoiding what our blogging friend refered to as his “biggest regret”.&lt;/p&gt;

&lt;p&gt;I’ve talked to a lot of people who live, eat and breathe programming. It’s hard to stand next to them without hearing about the latest library or tool they’re checking out and how what they’re building is awesome and going to revolutionize everything (or is useless but _ aren’t neural networks cool!?!_). Almost all of them echoed the earlier sentiment - programming as a profession wasn’t for them.&lt;/p&gt;

&lt;p&gt;How could this be? A group of people, granted the ability to do what they love for great pay &amp;amp; perks, all wanting to move on? It all comes down to:&lt;/p&gt;

&lt;h1&gt;
  
  
  People want to &lt;em&gt;make&lt;/em&gt; decisions rather than execute them
&lt;/h1&gt;

&lt;p&gt;Turns out science agrees on this: &lt;a href="http://www.theatlantic.com/health/archive/2016/03/people-want-power-because-they-want-autonomy/474669/"&gt;People want power because they want autonomy&lt;/a&gt;. Most of the time, folks desire to move up the career ladder not for pay, better title, or keys to the executive washroom (are those still a thing?) but because they wish to be able to exercise greater autonomy over their lives. &lt;a href="https://www.youtube.com/watch?v=u6XAPnuFjJc"&gt;Psychologist Daniel Pink agrees&lt;/a&gt; - he’s found that the three qualities that contribute most to workplace satisfaction and overall productivity are autonomy, mastery &amp;amp; purpose.&lt;/p&gt;

&lt;p&gt;I too, was bitten by the “Management = autonomy” bug. My original career goal was to rise up in the ranks of programmers, eventually crowning myself king of my own startup, the ultimate in autonomy (or so I thought). I carefully chose the work I did at each job to align with this goal - and succeeded, eventually earning the rank of a lead position (before the company ultimately collapsed, but that’s another story).&lt;/p&gt;

&lt;p&gt;During my last job hunt, I had two fantastic options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leader, with a few constraints&lt;/li&gt;
&lt;li&gt;Not Leader, with full autonomy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was it! I could capitalize on my previous work and &lt;em&gt;finally&lt;/em&gt; …not program. Something was wrong here - what did I ultimately want? When it came down to it, I wanted to write code. I love building things and I didn’t want to give that up. Sure, startups mean doing a little bit of everything but the success case everyone’s working towards means outsourcing all of your own work until you’ve forgotten all of the shortcuts to your favorite IDE. I chose the latter job, the one that would grant me the most autonomy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementers, Solvers, and Finders
&lt;/h2&gt;

&lt;p&gt;Could it be that we’ve utterly mischaracterized how career development as a programmer should work? The guiding trifecta of Junior, Regular, &amp;amp; Senior is &lt;a href="http://inmailfail.com/article/The-Fed-needs-to-cut-down-on-title-inflation.html"&gt;incredibly easy to game&lt;/a&gt; (A misguided company offered me a senior level job just under a year into my career). A word ceases to be useful when we can’t agree on its purpose - title relativism means a given title can convey entirely separate messages to different companies. Which is more impressive, a “Senior UI Engineer” or a “Javascript Architect”?&lt;/p&gt;

&lt;p&gt;If we’re to escape this situation where fantastic fanatic programmers can’t see themselves programming in three years, we need to couple our words to real world meaning. Instead of Jr/Sr nonsense (which already reeks of the years-of-experience antipattern), why don’t we talk about what the job will actually entail? Let’s define your job title by how much autonomy your day-to-day work gives you.&lt;/p&gt;

&lt;p&gt;Do you find that most of your time is simply closing tickets, and your team rarely considers your input? Your title is &lt;em&gt;Solution Implementer&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Are you given general problems and left to your own devices on how they’re fixed? When brainstorming, is your input considered by your teammates? You’re working as a &lt;em&gt;Problem Solver&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Are you given near-total autonomy in choosing what you work on? Can you tell your boss “That’s an interesting idea but my time would be better spent elsewhere” (and &lt;em&gt;not&lt;/em&gt; get fired on the spot)? You’re a &lt;em&gt;Problem Finder&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Our regretful fellow author of the post above spent most of his time as an Implementer. People (often non-technical) assigned concrete tasks without room for feedback or innovation. Every one of his stories shares the same problem: &lt;em&gt;He wasn’t given autonomy&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I don’t mean to say that everyone who’s at the Solution Implementer level should immediately quit their jobs, or that life as an Implementer de facto means you’re a bad programmer. Beginning programmers who are still learning the base concepts will thrive as Implementers &lt;em&gt;if&lt;/em&gt; handed solutions matching the challenge level they’re willing to accept. The mere task of implementing something provides plenty of opportunities to learn (in fact, I’d say it’s the only way to truly understand something). Beginners of all skill levels will get lost if thrown at a problem with too big of a scope for them to handle.&lt;/p&gt;

&lt;p&gt;One can’t remain a beginner forever. There needs to be a way for these implementers to level up. We, as a community, don’t have an agreed-upon way to take a budding programmer and hand them continually-increasing challenge. The standard practice in leveling up seems to be to quit and start hunting for a new job at the next level. This is why my standing advice to beginning programmers is to find a new job after six months (hopefully in the same company).&lt;/p&gt;

&lt;p&gt;It can be difficult to tell if a company is actually looking for a Problem Solver or the work is just Implementation in disguise. One org smell to look out for is the ratio of programmers to project/product managers. I’ve fallen for this, thinking I’d get to take charge of a frontend when what they really wanted me to do was slog through 17,000 issues in JIRA. Determining the true culture of a company is troublesome, you can start by &lt;a href="https://rkoutnik.com/articles/Questions-to-ask-your-interviewer.html"&gt;interviewing your interviewer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On the other hand, if our programmer does land that Solver job, they will start spreading their wings beyond the basics. At this point their opinion starts to mean something, and the challenges they face take on a new shape as their sphere of responsibility grows. There’s an entirely new set of skills to learn - suddenly effective communication means a whole lot more than “following the JIRA process correctly”. Solvers need to learn how to evangelize their favorite solutions and defend them against other Solvers who have different preferences.&lt;/p&gt;

&lt;p&gt;Solver is a enormous growth area and the typical Solver may spend years making mistakes, learning, and causing &lt;em&gt;new&lt;/em&gt; catastrophes until their knowledge grows to the point where they’re ready to make the final leap to Finder.&lt;/p&gt;

&lt;p&gt;Mid-size Startups (&amp;gt; 50 people) are a great place for Solvers - there’s plenty of problems begging for solutions and often Solvers can branch out into areas that would be verboten to them at a larger, established company. As the startup grows, so does their responsibility - this is a common way for a Solver to grow into a Finder. Another case is for a company to create fertile ground for Finders and recruit them directly.&lt;/p&gt;

&lt;p&gt;The final stage of programmer evolution is the Finder. These folks are considered experts in their chosen domain (and are prudent about others). Writing Finder job descriptions is an exercise in futility. As my boss put it: “I can’t tell you the specifics of what you’ll be doing here because your first task will be to figure that out.” A Finder will be able to anticipate problems before they happen, usually because they’ve been in that situation before. Finders are the canonical “&lt;a href="http://steve-yegge.blogspot.com/2008/06/done-and-gets-things-smart.html"&gt;Done and get things smart&lt;/a&gt;” that Steve Yegge likes to talk about. Empathy is a critical key in a Finder’s toolbox. Finders need to work with a variety of other folks without swinging the “I’m smart &amp;amp; because I said so” hammer (otherwise they’re &lt;a href="http://www.inc.com/jim-schleckser/why-netflix-doesn-t-tolerate-brilliant-jerks.html"&gt;Brilliant Jerks&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Finders need autonomy, by definition. Any job that puts significant restraints on what a programmer can &amp;amp; can’t do is a poor fit for a Finder. Poorly-managed startups love to hire smart people and then tell them what to do in precise detail. No one wins.&lt;/p&gt;

&lt;p&gt;My hope is this post will create shared vocabulary. This triumvirate of concepts can help great folks find the job that’s best for them. A company may be honestly seeking an Implementor, and effectively communicating that to a Solver or Finder will save both parties a lot of time.&lt;/p&gt;

&lt;p&gt;More importantly, I want programmers everywhere to realize that it’s possible to have autonomy while still writing code for a living. Some may find fulfillment in leadership (I know I do, the siren song has abated but is not gone) but plenty of hackers out there just want to make great things. There’s hope for us yet!&lt;/p&gt;

&lt;p&gt;Postscript: If this article rang true to you and you feel like you’re ready to level up, I’d love to hear from you. What brought you to your current job? What changed? How are you looking for the job that fits you?&lt;/p&gt;

&lt;p&gt;Let me know at: &lt;a href="//mailto:isf@rkoutnik.com"&gt;isf at rkoutnik.com&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
