<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Todd Schiller - software development</title><link href="https://toddschiller.com/" rel="alternate"></link><link href="https://toddschiller.com/feeds/tag/software-development.atom.xml" rel="self"></link><id>https://toddschiller.com/</id><updated>2016-05-04T00:00:00-04:00</updated><subtitle>Human ✘ Artificial Intelligence</subtitle><entry><title>The MBA guide to software development</title><link href="https://toddschiller.com/blog/the-mba-guide-to-software-development.html" rel="alternate"></link><published>2016-05-04T00:00:00-04:00</published><updated>2016-05-04T00:00:00-04:00</updated><author><name>Todd Schiller</name></author><id>tag:toddschiller.com,2016-05-04:/blog/the-mba-guide-to-software-development.html</id><summary type="html">This guide is for executives, managers, and entrepreneurs who want to make better strategic decisions about software. It’s designed to give you a baseline conceptual understanding of the software development process to help you buy software, build software, and interact with software development teams.</summary><content type="html">&lt;style scoped&gt;
	h1 {
		font-size: 2em;
	}
	h1.entry-title {
		font-size: 38.5px;
	}
	h2 {
		font-size: 1.5em;
		line-height: 1.2em;
	}
	h3 {
		font-size: 1.2em;
		line-height: 1em;
	}
&lt;/style&gt;
&lt;p&gt;&lt;a name="who-this-guide-is-for"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Who This Guide is For&lt;/h2&gt;
&lt;p&gt;This guide is for executives, managers, and entrepreneurs who want to
make better strategic decisions about software. It’s designed to give
you a baseline conceptual understanding of the software development
process to help you buy software, build software, and interact with
software development teams.&lt;/p&gt;
&lt;p&gt;Developers will also find this guide useful for improving their
communication with business stakeholders and clients.&lt;/p&gt;
&lt;p&gt;&lt;a name="executive-summary"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Executive Summary&lt;/h2&gt;
&lt;p&gt;Software development, like business, is social and
collaborative. Software projects fail when communication breaks down
between customers, business stakeholders, and developers. Practices
such as Agile aim to ensure that the necessary communication
occurs. However, there's no silver bullet — you must adapt
practices to meet your project's specific needs.&lt;/p&gt;
&lt;p&gt;Agile teams recognize that they don't know exactly what needs to be
built and how to build it. Instead, they seek to continuously deliver
value, identify problems early, and get feedback from their
users. They organize work around what users should be able to
accomplish rather than software features.&lt;/p&gt;
&lt;p&gt;Software quality can be managed just like any other requirement. The
same goes for software security, but it's difficult to estimate the
probability and cost of security incidents. Testing is perhaps the
most effective way to ensure quality. However, because testing can
only detect problems and not show the absence of problems, teams
should also consider code analysis tools and manual code review,
especially for security.&lt;/p&gt;
&lt;p&gt;Managing a software development project isn't fundamentally different
from managing any other project. However, managers should appreciate
that they likely have both a different personality and different time
management needs than their developers. Managers should also maintain
awareness of which technical decisions have the potential to impact
business outcomes now and in the future.&lt;/p&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;
&lt;div&gt;
&lt;style scoped&gt;
	ul.toc {

	}
	ul.toc li {
		margin-bottom: 0;
		font-size: 1em;
	}
&lt;/style&gt;
&lt;!-- markdownlint-disable MD013 --&gt;
&lt;ul class="toc"&gt;
	&lt;li&gt;&lt;a href="#what-is-software"&gt;What is Software?&lt;/a&gt;
		&lt;ul&gt;
		  &lt;li&gt;&lt;a href="#components-and-contracts"&gt;Components and Contracts&lt;/a&gt;
			  &lt;ul&gt;
				  &lt;li&gt;&lt;a href="#abstraction"&gt;Abstraction&lt;/a&gt;&lt;/li&gt;
				   &lt;li&gt;&lt;a href="#bugs"&gt;Bugs&lt;/a&gt;&lt;/li&gt;
				   &lt;li&gt;&lt;a href="#documentation"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
				   &lt;li&gt;&lt;a href="#design-patterns"&gt;Design Patterns&lt;/a&gt;&lt;/li&gt;
			  &lt;/ul&gt;
		  &lt;/li&gt;
		  &lt;li&gt;&lt;a href="#making-software-vs-making-cars"&gt;Making
	Software vs. Making Cars&lt;/a&gt;
	     &lt;ul&gt;
		 &lt;li&gt;&lt;a href="#software-maintenance"&gt;Software Maintenance&lt;/a&gt;&lt;/li&gt;
		 &lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href="#software-engineering-vs-scripting"&gt;Software Engineering vs. Excel vs. SQL vs. Scripting&lt;/a&gt;&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href="#software-development-lifecycle"&gt;The Software Development Lifecycle (SDLC)&lt;/a&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href="#user-stories"&gt;User Stories&lt;/a&gt;
		&lt;ul&gt;
			&lt;li&gt;&lt;a href="#parkinsons-law-of-triviality"&gt;Parkinson's Law of Triviality&lt;/a&gt;&lt;/li&gt;
		&lt;/ul&gt;
		&lt;/li&gt;
	&lt;li&gt;&lt;a href="#organizing-work"&gt;Organizing Work&lt;/a&gt;
		&lt;ul&gt;
		&lt;li&gt;&lt;a href="#sprints"&gt;Sprints&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#kanban"&gt;Kanban&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#sdlc-red-flags"&gt;Table: Signs of a Dysfunctional
	Software Development Lifecycle&lt;/a&gt;&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
		&lt;li&gt;&lt;a href="#continuous-integration-and-deployment"&gt;Continuous Integration and Deployment&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="#version-control"&gt;Version Control&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="#meetings"&gt;Meetings&lt;/a&gt;
		&lt;ul&gt;
		&lt;li&gt;&lt;a href="#scrums-and-stand-ups"&gt;Scrums and Stand-ups&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#post-mortems-and-retrospectives"&gt;Post-Mortems and Retrospectives&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#example-post-mortem"&gt;Figure: Sample Post-Mortem Analysis&lt;/a&gt;&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href="#tracking-work"&gt;Tracking Work&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="#managing-software-quality"&gt;Managing Software
	Quality&lt;/a&gt;
		&lt;ul&gt;
				&lt;li&gt;&lt;a href="#testing"&gt;Testing&lt;/a&gt;&lt;/li&gt;
				&lt;li&gt;&lt;a href="#automated-code-analysis"&gt;Automated Code
	Analysis&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="#code-review"&gt;Code Review&lt;/a&gt;&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href="#technical-debt"&gt;Anticipating the Future (controlling Technical Debt)&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href="#managing-development-teams"&gt;Managing Development Teams&lt;/a&gt;
		&lt;ul&gt;
			&lt;li&gt;&lt;a href="#time-management"&gt;Time Management and
	Interruptions&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="#developer-tools"&gt;Developer Tools&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="#personality"&gt;Personality Mismatch&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="#skills-acquisition"&gt;Skills Acquisition and Novelty&lt;/a&gt;&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href="#appendix-hot-trends"&gt;Appendix: Hot Trends&lt;/a&gt;
		&lt;ul&gt;
			&lt;li&gt;&lt;a href="#big-data"&gt;Big Data&lt;/a&gt;&lt;/li&gt;
			&lt;li&gt;&lt;a href="#cloud-computing"&gt;Cloud Computing,
	Infrastructure-as-a-Service, Platform-as-a-Service, and
	Beyond&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="#microservices"&gt;From Monolith to
	Microservices&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="#open-source-software"&gt;Open Source Software&lt;/a&gt;
		&lt;ul&gt;
			&lt;li&gt;&lt;a href="#oss-licensing"&gt;Licensing&lt;/a&gt;&lt;/li&gt;
			&lt;li&gt;&lt;a href="#oss-support"&gt;Support&lt;/a&gt;&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href="#footnotes"&gt;Footnotes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;!-- markdownlint-enable MD013 --&gt;
&lt;p&gt;&lt;a name="what-is-software"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;What is Software?&lt;/h2&gt;
&lt;p&gt;&lt;a name="components-and-contracts"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Components and Contracts&lt;/h3&gt;
&lt;p&gt;The most effective way to think about software is as a set of
components and contracts (agreements) between those components. The
contracts have provisions such as: &lt;i&gt;&amp;quot;If you give me X, then I'll do
Y&amp;quot; and &amp;quot;If you instead give me Z, I will crash or do something
unpredictable.&amp;quot;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;a name="abstraction"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Abstraction&lt;/h4&gt;
&lt;p&gt;Thinking about software as components and contracts can help you
understand how it works at multiple levels. Software engineers call
this way of thinking — envisioning multiple components as a
single component — abstraction. Abstraction isn't unique to
software engineering — it's how all humans handle
complexity. For example, a CEO of a large company thinks in terms of
business units, such as accounting and sales, rather than the
responsibilities of each accountant and salesperson.&lt;/p&gt;
&lt;p&gt;To demonstrate the concept of abstraction, let's take the Event
Ticketing app on your phone. At a high level, you can think of it as a
single component with the following contract with the customer: &lt;i&gt;&amp;quot;If
you select an available event and give me valid payment information, I
will reserve you a spot and show you a confirmation. Otherwise, I will
show you an error.&amp;quot;&lt;/i&gt;&lt;/p&gt;
&lt;div style="text-align:center; margin-bottom: 2em;"&gt;
&lt;img loading="lazy" decoding="async" src="/assets/images/event_ticketing1.png"
    alt="Event ticketing app high-level view" /&gt;
&lt;/div&gt;
&lt;p&gt;A level down, the software can be thought of as having two components:
the app that's running on the customer’s phone, and a ticket
processing server. The app has a contract with both the customer and
the server. The contract with the server states, &lt;i&gt;&amp;quot;If you send an
event identifier and payment information in a particular format, I
will send you a confirmation code, an error that the event is
sold-out, or an error that the payment was invalid. Otherwise, I will
send you a generic error.&amp;quot;&lt;/i&gt;&lt;/p&gt;
&lt;div style="text-align:center; margin-bottom: 2em;"&gt;
&lt;img loading="lazy" decoding="async" src="/assets/images/event_ticketing2.png"
    alt="Event ticketing app component view" /&gt;
&lt;/div&gt;
&lt;p&gt;Yet another level down, the ticket processing component might actually
consist of both a component for processing payments and a database
component for storing events and orders. We can keep conceptually
breaking down the software until we hit the lowest level — each
line of code is a component with a contract.&lt;/p&gt;
&lt;p&gt;&lt;a name="bugs"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Bugs&lt;/h4&gt;
&lt;p&gt;A bug occurs when a component doesn't do what it agreed to in its
contract. But remember, in some cases, unexpected behavior might just
be a component dutifully executing a bad contract! Just as with a
legal contract, you have to be aware of loopholes, especially when
you're up against an adversarial counterparty, such as a hacker.&lt;/p&gt;
&lt;p&gt;&lt;a name="documentation"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Documentation&lt;/h3&gt;
&lt;p&gt;Developers communicate the intended contract for a component using
documentation. When you hear developers complain about bad
documentation, they're complaining that the software’s functionality
and contracts are not clear. In these cases, if they're lucky, the
code is available and they can try to guess what the contract
is. Without a documented contract though, it can be impossible to
distinguish a bug (unintended) from a feature (intended).&lt;/p&gt;
&lt;p&gt;&lt;a name="design-patterns"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Design Patterns&lt;/h4&gt;
&lt;p&gt;Over time, common design patterns have been developed for putting
together components. Like business frameworks (e.g., Porter's 5
Forces, a Business Model Canvas, etc.), design patterns provide a
common conceptual language for discussing and building software. Their
strengths and limitations are generally well understood and are taught
as part of a software engineering education.&lt;/p&gt;
&lt;p&gt;&lt;a name="making-software-vs-making-cars"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Making Software vs. Making Cars&lt;/h3&gt;
&lt;p&gt;The first automobile was built in 1768 — it was steam
powered. Cars wouldn't hit production until over a hundred years later
when, in 1886, Karl Benz produced several copies of the same
car. Today we understand the basics of automotive engineering. And,
because cars are bound by the laws of physics, we can build in a
margin of error that ensures reliable performance and safety under
most conditions.&lt;/p&gt;
&lt;p&gt;Compared to automotive engineering, software engineering is a young
profession. Software engineers regularly have to design and build
systems that haven't been built before. And, unlike cars, software is
subject to environments that don't follow the laws of
physics. Therefore, it shouldn't come as a surprise that only 39% of
IT projects are completed on-time, on-scope, and
on-budget &lt;a href="#ref-1"&gt;[1]&lt;/a&gt;. The good
news is that software engineering, as a profession, is continually
learning how to make more types of software. One prominent example in
business are CRUD (create, read, update, delete) applications for
performing business data entry and data management.&lt;/p&gt;
&lt;p&gt;&lt;a name="software-maintenance"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Software Maintenance&lt;/h4&gt;
&lt;p&gt;When you take your car into the shop for maintenance, the mechanic
might change the oil and rotate the tires. Software maintenance, on
the other hand, often isn't maintenance — it’s modifying the
software to meet changing business needs. In this way, software
maintenance is akin to asking your mechanic to attach a propeller to
your car so that it can fly.&lt;/p&gt;
&lt;div style="text-align:center; margin-bottom: 10px;"&gt;
&lt;img loading="lazy" decoding="async" src="/assets/images/helicopter_car.jpg" alt="A helicopter-car"
style="height: 200px" /&gt;
&lt;div style="font-size: 0.9em;"&gt;
Figure 1: Is it a car? Is it a helicopter? No &amp;mdash; it's &lt;a href="http://blog.modernmechanix.com/this-helicopter-car-flies-over-traffic/"&gt;Helicopter-Car&lt;/a&gt;!
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a name="software-engineering-vs-scripting"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Software Engineering vs. Excel vs. SQL vs. Scripting&lt;/h3&gt;
&lt;p&gt;You've constructed glorious spreadsheets in Excel, queried databases
with SQL, and even scripted in Python — software engineering
doesn't seem so hard! What you’re missing is that you’ve typically
only had to worry about what's called the happy path, taking a known
input and computing an output. When building software, developers are
forced to consider all paths, not just the happy ones. Exceptions can
arise accidentally from misbehaving components or even because a
malicious hacker is attacking your software. Software engineers have
to build software that works across a range of inputs, across time,
and with multiple users and components interacting
simultaneously. Resilience is hard and time consuming to get right.&lt;/p&gt;
&lt;p&gt;&lt;a name="software-development-lifecycle"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;The Software Development Lifecycle (SDLC)&lt;/h2&gt;
&lt;p&gt;Software development, like business, is social and
collaborative. Communication is key. Product managers (PMs)
communicate with customers to determine needs. PMs communicate with
developers to create requirements and schedules. Developers
communicate to hash out specifications, coordinate development, and
keep the PM up-to-date on progress and problems.&lt;/p&gt;
&lt;p&gt;Projects fail when communication fails. Executives fail to provide
vision. Product managers fail to understand customer needs. Developers
fail to prioritize. Sub-teams fail to coordinate. In 1999, the $125MM
Mars Climate Orbiter famously disintegrated in the Martian atmosphere
due to a software bug. Why? – the ground control software was speaking
in Imperial units (pound-seconds) and the spacecraft was listening for
metric (newton-seconds).&lt;/p&gt;
&lt;p&gt;All of the practices you hear about — Agile, Waterfall,
etc. — are designed to ensure that necessary communication
occurs. Unfortunately, there's no silver bullet for
communication &lt;a href="#ref-2"&gt;[3]&lt;/a&gt;. Instead, you must adopt and adapt
practices to fit the
specific needs of your project.&lt;/p&gt;
&lt;p&gt;In the past, the dominant practice for software development was
Waterfall. With Waterfall, a team would follow a sequential process of
first gathering all of the requirements, then designing the system,
implementing it, verifying it, and finally deploying it. Teams using
Waterfall often learned the hard way that it's nearly impossible to
get each step right the first time around.&lt;/p&gt;
&lt;p&gt;This guide presents Agile software development practices. Agile has
been successful because, unlike Waterfall, it recognizes and
accommodates for the reality that teams rarely know exactly what they
need to build and how to build it.&lt;/p&gt;
&lt;p&gt;&lt;a name="user-stories"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;User Stories&lt;/h3&gt;
&lt;p&gt;In Agile, teams describe the software requirements with User
Stories. Each User Story details the steps a user will take to
accomplish a goal. Compared to describing software features (what
functionality the software has), User Stories place the emphasis on
the value that the software provides to the customer.&lt;/p&gt;
&lt;p&gt;As part of creating user stories, teams create mockups (wireframes)
that show the user completing the story. Compared to building
prototypes and demos, mockups are an inexpensive way to facilitate
communication and identify problems early.&lt;/p&gt;
&lt;p&gt;&lt;a name="parkinsons-law-of-triviality"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Parkinson's Law of Triviality&lt;/h4&gt;
&lt;p&gt;Teams often spend a disproportionate amount of time discussing
surface-level and easy-to-grasp issues &lt;a href="#ref-3"&gt;[3]&lt;/a&gt;. For these
issues, people feel
more entitled to have opinion. For example, a team can endlessly
discuss where a button should go in a phone app but may spend little
time discussing the best way to implement encryption to protect
sensitive data.&lt;/p&gt;
&lt;p&gt;&lt;a name="organizing-work"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Organizing Work&lt;/h3&gt;
&lt;p&gt;&lt;a name="sprints"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Sprints&lt;/h4&gt;
&lt;p&gt;Agile teams break work into 1-4 week long sprints. The short
turn-around time is designed to regularly deliver business value and
create ample opportunity for feedback.&lt;/p&gt;
&lt;p&gt;At the beginning of a sprint, the team sets the scope for what they're
trying to learn and accomplish. During the sprint, the team can adjust
the scope of the sprint based on their progress and what they've
learned so far.&lt;/p&gt;
&lt;p&gt;To plan a sprint, a team has to estimate how long tasks will
take. Estimates are notoriously inaccurate and should be
monitored/revised during the sprint. Despite their inaccuracy,
estimates can be valuable in eliciting differences in
understanding. For example, if one developer expects a story to take
one hour and another expects it to take ten hours, the two developers
likely have a different understanding of what's required.&lt;/p&gt;
&lt;p&gt;&lt;a name="kanban"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Kanban&lt;/h4&gt;
&lt;p&gt;For some projects (e.g., ongoing website maintenance), it may make
sense to eliminate sprints and instead focus on continuously
delivering value. One system for this approach is Kanban, which is
inspired by Toyota's lean manufacturing process of the same
name. Teams practicing Kanban perform a continuous flow of work. For
example:&lt;/p&gt;
&lt;p&gt;Gather Requirements → Develop → Test → Deploy
→ Collect Feedback&lt;/p&gt;
&lt;p&gt;To prevent bottlenecks, teams place limits on how much work can exist
at each stage in the process at a given time. For example, if work is
getting backed up in testing, a team might temporarily shift resources
from development and requirements gathering to quality assurance. The
team then deploys the tested changes to deliver value and get feedback
from users.&lt;/p&gt;
&lt;div&gt;
&lt;style scoped&gt;
    .sdlc {
		border: 1px solid ;
	}
	.sdlc td {
		border: 1px solid black;
		vertical-align: top;
	}
	.sdlc tbody td {
		padding: 5px;
	}
	.sdlc td {
		font-family: 'Open Sans', sans-serif;
		font-size: 1em;
		line-height: 1.5em;
	}
	.sdlc li {
		margin-bottom: 0;
		font-size: 1em;
	}
	.table-header {
		background-color: #2D3043;
		color: white;
	}
	.table-header th {
		font-size: 1.2em;
		padding: 5px;
	}
&lt;/style&gt;
&lt;!-- markdownlint-disable MD013 --&gt;
&lt;p&gt;&lt;a name="sdlc-red-flags"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;table class="sdlc"&gt;
	&lt;thead&gt;
		&lt;tr class="table-header"&gt;
			&lt;th colspan=2&gt;Signs of a Dysfunctional Software Development Lifecycle&lt;/th&gt;
		&lt;/tr&gt;
		&lt;tr class="column-headers"&gt;
			&lt;th&gt;Red Flag&lt;/th&gt;
			&lt;th&gt;Possible Causes&lt;/th&gt;
		&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
		&lt;tr&gt;
			&lt;td&gt;Your team is always in crunch mode&lt;/td&gt;
			&lt;td&gt;
				&lt;ul&gt;
					&lt;li&gt;The team's estimation process is poor&lt;/li&gt;
					&lt;li&gt;
						The team is not effectively managing the scope
	of sprints
				   &lt;/li&gt;
			   &lt;li&gt;
				   The team is not pipelining work and accounting for interdependencies
			   &lt;/li&gt;
				&lt;/ul&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Work regularly gets bottle-necked at the end of a sprint&lt;/td&gt;
		 &lt;td&gt;
			 &lt;ul&gt;
				 &lt;li&gt;The team is underestimating certain parts of the
	process&lt;/li&gt;
		&lt;li&gt;The team is not pipelining work and accounting for
	interdependencies&lt;/li&gt;
			 &lt;/ul&gt;
		 &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Sprint deadlines regularly slip&lt;/td&gt;
			&lt;td&gt;
				&lt;ul&gt;
					&lt;li&gt;The team is not effectively managing the scope
	of sprints&lt;/li&gt;
		&lt;li&gt;The team doesn't have a way of &lt;i&gt;continuously&lt;/i&gt; delivering value to the customer&lt;/li&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Work is regularly finished right at the end of the
	sprint and is low quality&lt;/td&gt;
		&lt;td&gt;
			&lt;ul&gt;
				&lt;li&gt;The team is cutting corners to hit unrealistic
	estimates or deadlines&lt;/li&gt;
	&lt;li&gt;The team's quality assurance process is defective&lt;/li&gt;
			&lt;/ul&gt;
		&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;!-- markdownlint-enable MD013 --&gt;
&lt;p&gt;&lt;a name="continuous-integration-and-deployment"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Continuous Integration and Deployment&lt;/h3&gt;
&lt;p&gt;Agile teams integrate their changes into the software on a regular
basis rather than integrating all of their changes at the end of a
sprint. Continuous integration allows problems to be detected early,
and with the help of tools, automatically.&lt;/p&gt;
&lt;p&gt;The shift to Software-as-a-Service (SaaS) has enabled teams to take
continuous integration a step further. Agile teams can automatically
deploy changes to users once the changes have passed automated checks
and/or received approval. Advanced teams conduct staged rollouts,
allowing them to catch problems and get feedback from a subset of
users before they deploy changes to everyone.&lt;/p&gt;
&lt;p&gt;&lt;a name="version-control"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Version Control&lt;/h3&gt;
&lt;p&gt;Version Control (such as &lt;a href="https://git-scm.com/"&gt;Git&lt;/a&gt;
or &lt;a href="https://www.mercurial-scm.org/"&gt;
Mercurial&lt;/a&gt;) is a tool for keeping track
of the software's source, including its source code, documentation,
configuration, and data schemas. Version Control is similar to
Microsoft Word's Track Changes features, but it provides better
support for merging edits from multiple team members.&lt;/p&gt;
&lt;p&gt;Additionally, as the name suggests, Version Control enables team
members to work on multiple versions of the software at the same time,
and switch between them. For example, one developer may be fixing bugs
in the production version of the software while another is prototyping
improvements.&lt;/p&gt;
&lt;p&gt;&lt;a name="meetings"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Meetings&lt;/h3&gt;
&lt;p&gt;&lt;a name="scrums-and-stand-ups"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Scrums and Stand-ups&lt;/h4&gt;
&lt;p&gt;Agile teams hold scrums (also called stand-ups) to promote awareness
and uncover previously unknown interdependencies and blockages. Team
members take turns saying what they've accomplished since the previous
stand-up, what they're working on next, and any risks and impediments
they foresee. Some teams hold these short meetings every day. However,
you should always consider other ways (e.g., email updates) of
accomplishing the same goals.&lt;/p&gt;
&lt;p&gt;&lt;a name="post-mortems-and-retrospectives"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Post-Mortems and Retrospectives&lt;/h4&gt;
&lt;p&gt;After a sprint, major deliverable, or incident, Agile teams hold
post-mortems (also called retrospectives). The goals of a post-mortem
are to determine (1) what went well or badly, (2) why, and (3) what to
do about it. Ideally, you want to get to the root cause of an
issue. One effective way to diagnose a problem (or positive outcome)
is by asking the &amp;quot;5 Whys&amp;quot; &lt;a href="#ref-4"&gt;[4]&lt;/a&gt;. By repeatedly asking &amp;quot;why?&amp;quot;,
you uncover a
chain of causality.&lt;/p&gt;
&lt;p&gt;When trying to determine the root cause, don't de-personalize —
be specific about each individual's responsibilities and the actions
they took &lt;a href="#ref-5"&gt;[5]&lt;/a&gt;. Additionally, recognize that in some cases,
the process is
flawed (e.g., is based on unrealistic expectations). In these cases,
you have to explore who designed the process — or failed to
design — the process.&lt;/p&gt;
&lt;p&gt;&lt;a name="example-post-mortem"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div align="center"&gt;
	&lt;img loading="lazy" decoding="async" src="/assets/images/post_mortem.png" alt="Example of a
	post-mortem analysis"/&gt;
	&lt;div style="font-size:.9em; width: 90%" align="left"&gt;
Figure 2: A partial post-mortem of a service outage. The analysis
clearly identifies who was involved, what their responsibilities were, and what
actions they took (or failed to take). The analysis explores multiple
possibilities instead of just one line of reasoning. The analysis also makes
blunt statements about what people are like (e.g., John is over-confident).
Your ability to go to that level will depend on the culture of your company
and team. Based on this analysis, what changes would you suggest?
	&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a name="tracking-work"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Tracking Work&lt;/h3&gt;
&lt;p&gt;An Issue Tracker (such as &lt;a href="https://www.atlassian.com/software/jira"&gt;
JIRA&lt;/a&gt;) is a database of all the user
stories,
bugs, and tasks for a project as well as discussions about
them. Additionally, a team can track information such as how important
an issue is, how long it's estimated to take, who is working on it,
and its current status.&lt;/p&gt;
&lt;p&gt;An Issue Tracker is most effective when the entire team is using
it. When only part of the team is using it, team members have to hunt
down information: was that requirement in an email from last month?
Did the requirement come from a phone call? Why did that requirement
change? Fragmented information wastes time and is a breeding ground
for software bugs.&lt;/p&gt;
&lt;p&gt;Teams can also create workflows for different types of
issues. Workflows allow the team to enforce policies such as, &amp;quot;Each
user story we've implemented must be signed off on by the product
manager before it's delivered to the customer.&amp;quot; While workflows ensure
that particular communications occurred, having overly complex
workflows can impair a team's agility. The workflows you implement
should be grounded in the needs of your project, such as to address a
problem analyzed in a post-mortem.&lt;/p&gt;
&lt;p&gt;&lt;a name="managing-software-quality"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Managing Software Quality&lt;/h3&gt;
&lt;p&gt;Software quality is a requirement to be managed like any other
requirement. Investments in quality should be tied to user
needs. Software security can also be managed as a
requirement. However, the probability and impact of security
vulnerabilities are hard to estimate.&lt;/p&gt;
&lt;p&gt;To effectively manage software quality, the team has to understand
their software's risk unique profile: which components are the
riskiest, what kinds of failures can occur, and how the failure of one
component failing might impact the others. Based on the risk profile,
the team can decide on the appropriate architectural changes,
development practices, and development tools.&lt;/p&gt;
&lt;p&gt;Quality checks are most effective when they're automated, as automated
checks enable quality to be continuously monitored and enforced. The
upfront and maintenance costs of automated checks are strongly linked
to how the components are organized. Often, code that is organized to
be conducive to checking is also more conducive to development, as
automated checks encourage a clearer separation of responsibilities
between components.&lt;/p&gt;
&lt;p&gt;&lt;a name="testing"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Testing&lt;/h4&gt;
&lt;p&gt;Testing is perhaps the best approach to measuring and enforcing
quality. Every test has two parts: (1) an input and (2) a check that
the software did the right thing.&lt;/p&gt;
&lt;p&gt;The quality of a test suite is generally measured by how much of the
software it tests (code coverage). The reasoning is that a test can't
find bugs in code it doesn't execute. The most common way of
calculating coverage is statement coverage, which measures the
percentage of lines of code the tests execute. The problem with
statement coverage is that while a majority of code is on the happy
path, most bugs occur as a result of the developer not accounting for
a certain scenario. Therefore, a team may also want to consider
metrics that measure decision coverage, the percentage of logical
paths that a test suite executes. Regardless of the method you use, be
aware of its limitations so you aren't lured into a false sense of
confidence.&lt;/p&gt;
&lt;p&gt;While tests are good for detecting problems, they can't show the
absence of bugs &lt;a href="#ref-6"&gt;[6]&lt;/a&gt;. For example, with testing, it's nearly
impossible to
demonstrate that only certain users have access to confidential
data. For these kinds of safety requirements, a team has to adopt a
combination of testing, code analysis tools, and code review.&lt;/p&gt;
&lt;p&gt;&lt;a name="automated-code-analysis"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Automated Code Analysis&lt;/h4&gt;
&lt;p&gt;Code analysis tools &amp;quot;read&amp;quot; a program and automatically identify corner
cases and what might go wrong. Remember the Mars Orbiter that
disintegrated in the atmosphere? Today's code analysis tools can
automatically discover that Imperial units are being used where metric
units are expected. Like an automated test suite, these checks can be
run with every change to the software.&lt;/p&gt;
&lt;p&gt;You can think of code analysis tools as being similar to grammar and
spell-check in Microsoft Word. Even though they can catch a lot of
problems (and sometimes things that aren't actually problems), you’ll
still want to have someone review your paper for content and
style. This is where code review comes in.&lt;/p&gt;
&lt;p&gt;&lt;a name="code-review"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Code Review&lt;/h4&gt;
&lt;p&gt;Code review is the practice of having developers review each other's
code. An independent review uncovers bugs and potential ways of
improving the code. As an added benefit, code reviews reduce
operational risk by ensuring that multiple developers are familiar
with each part of the software. Additionally, code review can be a
good opportunity to mentor junior developers.&lt;/p&gt;
&lt;p&gt;&lt;a name="technical-debt"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Anticipating the Future (controlling Technical Debt)&lt;/h3&gt;
&lt;p&gt;Whenever a team takes a shortcut, they might have to make extra
efforts in the future to compensate. The shortcuts that build up over
time result in technical debt. The team pays &amp;quot;interest&amp;quot; on this debt
in that future changes require more resources to implement. A team can
pay down the debt by refactoring — re-organizing the code to
make it easier to understand and maintain.&lt;/p&gt;
&lt;p&gt;As you know, debt can actually be a good way to finance a
business. The same is true for technical debt, but you should note
that technical debt differs from financial debt in three key ways: (1)
you don't necessarily know when you’re going to pay interest, (2) you
sometimes never have to pay interest, (3) you can sometimes walk away
from your debt without penalty.&lt;/p&gt;
&lt;p&gt;Teams can also go too far in the other direction: they build
contingencies for future capabilities that they'll never need. The
response to this is &amp;quot;You Aren't Going to Need It!&amp;quot; (YAGNI).&lt;/p&gt;
&lt;p&gt;Effectively navigating technical debt requires strong communication
between the business stakeholders and developers. Developers are not
necessarily in the best position to know the probability of certain
requirements. Similarly, business stakeholders don't know how certain
development decisions will impact development time and costs.&lt;/p&gt;
&lt;p&gt;&lt;a name="managing-development-teams"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Managing Development Teams&lt;/h2&gt;
&lt;p&gt;Managing a development team isn't fundamentally different than
managing other teams. However, there are some general areas you should
be aware of due to the nature of the work.&lt;/p&gt;
&lt;p&gt;&lt;a name="time-management"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Time Management and Interruptions&lt;/h3&gt;
&lt;p&gt;Software developers have to keep a lot of information in their head at
once. The cost of switching tasks is high. It can take anywhere from
10-15 minutes for a developer to recover from a 5-minute
interruption &lt;a href="#ref-7"&gt;[7]&lt;/a&gt;. Managers need to allow developers blocks
of time to make
progress. Similarly, developers need to self-manage their distractions
(chat, notifications, etc.). Responsiveness expectations should
balance the need for questions to be answered quickly with the need
for developers to have uninterrupted work time.&lt;/p&gt;
&lt;p&gt;&lt;a name="developer-tools"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Developer Tools&lt;/h3&gt;
&lt;p&gt;Good developers are expensive. You can improve the return on your
investment by ensuring developers have access to the best tools money
can buy. A top-of-the-line computer (memory, monitors, etc.) is an
especially strong investment due to low prices.&lt;/p&gt;
&lt;p&gt;&lt;a name="personality"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Personality Mismatch&lt;/h3&gt;
&lt;p&gt;On the Myers-Briggs scale, developers show a preference toward
Judgement (structure and decisions) &lt;a href="#ref-8"&gt;[8]&lt;/a&gt;. Conversely,
entrepreneurs lean
toward Perceiving (freestyle thinking and staying open to
options) &lt;a href="#ref-9"&gt;[9]&lt;/a&gt;. If
you also lean toward Perceiving, recognize that you are likely to find
it draining to hammer out detailed requirements with
developers. Conversely, recognize that many developers will be
frustrated by what they view as a lack of clarity from you. By
accounting for differences in personality types and communication
styles, you can adapt a team's practices to streamline communication
and boost motivation.&lt;/p&gt;
&lt;p&gt;&lt;a name="skills-acquisition"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Skills Acquisition and Novelty&lt;/h3&gt;
&lt;p&gt;Like any professional, developers want improve to their skillset and
do interesting work.&lt;/p&gt;
&lt;p&gt;At its worst, this desire leads to something called resume-driven
development. A developer will choose the latest, sexiest, technology
instead of a relatively boring, but battle-proven
method. Alternatively, a developer may choose to re-write some
software from scratch instead of modifying legacy software.&lt;/p&gt;
&lt;p&gt;Undoubtedly, these are sometimes the right decisions. However, a
developer likely does not have sufficient context to make the best
decision for the business. For example, a technology might provide a
large enough advantage to offset the time required for that developer
to learn the technology, but did the developer also factor in the risk
of that technology being abandoned by the industry? How about the cost
to hire new developers with those skills to maintain the system?
Similarly, it's easy for developers to underestimate the vast amount
of business expertise that is often hidden within a legacy system.&lt;/p&gt;
&lt;p&gt;&lt;a name="appendix-hot-trends"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Appendix: Hot Trends&lt;/h2&gt;
&lt;p&gt;&lt;a name="big-data"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Big Data&lt;/h3&gt;
&lt;p&gt;In practice, big data is data that can't be analyzed on a single
computer. Typically, this means that the data is bigger than the
memory (RAM) on the machine. These days, computers can support a lot
of memory, so chances are your company has small data. Small data is
good because standard development is a lot cheaper than having to
deploy and program for a big data system (e.g., Hadoop or Spark).&lt;/p&gt;
&lt;p&gt;If buying a more powerful computer doesn't make your data seem small,
there are often ways to make your data smaller in order to analyze
it. For example, a dataset with the values “Male&amp;quot; and &amp;quot;Female&amp;quot; can be
made 56x smaller by encoding the information as either 0 or 1. A
little creativity can go a long way in avoiding complexity and saving
on development time and costs.&lt;/p&gt;
&lt;p&gt;&lt;a name="cloud-computing"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Cloud Computing, Infrastructure-as-a-Service, Platform-as-a-Service, and Beyond&lt;/h3&gt;
&lt;p&gt;In 2013, the popular messaging app WhatsApp had 200 million active
users and a staff of only 50 people. In 2014, it had 600 million
active users and was acquired by Facebook for $19BB. WhatsApp was able
to achieve this scale and leverage because of cloud computing.&lt;/p&gt;
&lt;p&gt;Cloud computing provides a flexible pool of resources for teams to use
when they need them. The first cloud computing was
Infrastructure-as-a-Service (IaaS), providing physical computing
resources on-demand. IaaS eliminated the need for teams to provision
and manage their own hardware in a data center. Platform-as-a-Service
(PaaS) went a step further and eliminated the need for a team to
configure and administer those servers. PaaS frees the team to focus
on the core business logic.&lt;/p&gt;
&lt;p&gt;Over time, cloud computing has continued &amp;quot;up the stack&amp;quot; by packaging
capabilities and services on top of the lower layers. One prominent
example is Machine-Learning-as-a-Service (MLaaS). MLaaS gives teams
the ability to train models over vast amounts of data without having
to administer machines or deploy machine learning software.&lt;/p&gt;
&lt;p&gt;Teams that leverage cloud computing are making a trade-off between
convenience and flexibility. The further up the stack a team goes, the
more decisions they've ceded to the cloud computing provider. A lack
of flexibility can make certain changes impossible. For these changes,
the team will have to drop down a level to implement their custom
logic. Additionally, due to differences in services, it can take
significant effort to switch providers. A team can potentially become
locked-in to a provider that has a steep pricing structure.&lt;/p&gt;
&lt;p&gt;&lt;a name="microservices"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;From Monolith to Microservices&lt;/h3&gt;
&lt;p&gt;A monolith is software written as a single service running on a single
server (or multiple copies of the same service across multiple
servers). A recent trend is to attempt to break up the monolith into
multiple different microservices, each serving a specific purpose. In
theory, microservices are supposed to make your software more
resilient and enable sub-teams to work independently. In practice, the
benefits are more nuanced.&lt;/p&gt;
&lt;p&gt;The primary limitation of microservices is that splitting software
into multiple parts doesn't, by itself, eliminate dependencies. If you
have an Event Ticketing system, moving payment processing to its own
microservice doesn't eliminate the dependency on payment
processing. When the payment processing system fails, customers still
won't be able to buy tickets. Furthermore, the payment team can’t work
completely independently. The team still has to coordinate with the
other teams to determine the contract (agreement) between the payment
processing microservice and the other services.&lt;/p&gt;
&lt;p&gt;Additionally, the design patterns and development tools dealing with
microservices are relatively immature. A team needs to critically
examine the conditions under which they can actually realize the
benefits of microservices.&lt;/p&gt;
&lt;p&gt;&lt;a name="open-source-software"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Open Source Software&lt;/h4&gt;
&lt;p&gt;Open Source Software (OSS) is software for which the source code is
available and licensed so that developers can modify and share
it. Though not technically accurate, the term has come to refer to
software that is developed in the open and is made available at no
monetary cost.&lt;/p&gt;
&lt;p&gt;Teams should evaluate Open Source Software just as they would any
other software.&lt;/p&gt;
&lt;p&gt;&lt;a name="oss-licensing"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Licensing&lt;/h4&gt;
&lt;p&gt;Permissive licenses, such as the MIT license, allow you to incorporate
the code into proprietary software. Copy-left licenses, such as the
GNU Public License, &amp;quot;contaminate&amp;quot; your software's licensing, requiring
you to distribute derivative works using the the same licensing. In
this case, you may be required to release the source code for part or
all of your software.&lt;/p&gt;
&lt;p&gt;&lt;a name="oss-support"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Support&lt;/h4&gt;
&lt;p&gt;Some Open Source Software is supported by a company. However, being
supported by a company does not mean that the company has any
obligation to provide support to your team now or in the future.&lt;/p&gt;
&lt;p&gt;Before deciding to use a project, a team should evaluate the health of
that project and its community, including what level of support they
can expect. To perform this evaluation, look at all the available
information, including release history, the Issue Tracker, mailing
lists, and popular community forums (e.g., Stack Overflow, the most
popular Q&amp;amp;A site for developers). A team will likely have to build
missing features or fix bugs impacting their particular project. If a
feature isn't already available or on a roadmap, it’s likely not a
priority for the project's developers. Therefore, a team’s developers
should also review the Open Source Software's source code to evaluate
its quality.&lt;/p&gt;
&lt;p&gt;&lt;a name="footnotes"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Footnotes&lt;/h2&gt;
&lt;p&gt;&lt;a name="ref-1"&gt;&lt;/a&gt;&lt;span&gt;[1]&lt;/span&gt; &lt;a
href="https://www.versionone.com/assets/img/files/CHAOSManifesto2013.pdf"&gt;CHAOS
Manifesto 2013: Think Big, Act Small&lt;/a&gt;. In 2012, large projects (with a cost
of
labor over $10MM) only had a success rate of 10%. Small projects
(with a cost of labor under $1MM) had a success rate of 76%.&lt;/p&gt;
&lt;p&gt;&lt;a name="ref-2"&gt;&lt;/a&gt;&lt;span&gt;[2]&lt;/span&gt;
&lt;a href="http://www.cs.nott.ac.uk/~pszcah/G51ISS/Documents/NoSilverBullet.html"&gt;
No Silver Bullet: Essence and Accidents of Software Engineering
&lt;/a&gt; is a famous essay by Frederick P. Brooks, Jr. It's part of &lt;a
href="http://www.amazon.com/Mythical-Man-Month-Software-Engineering-Anniversary/dp/0201835959"&gt;The
Mythical Man Month&lt;/a&gt;, perhaps the most influential book on software
project management.&lt;/p&gt;
&lt;p&gt;&lt;a name="ref-3"&gt;&lt;/a&gt;&lt;span&gt;[3]&lt;/span&gt;
&lt;a
href="http://www.amazon.com/Parkinsons-Law-Pursuit-Progress-Business/dp/0140091076"&gt;Parkinson's
Law, or the Pursuit of Progress.
&lt;/a&gt;Parkinson's main law is that work will expand to fill the time
allotted. Parkinson’s Law of Triviality is also commonly called
bike-shedding — Parkinson had observed a finance committee spend more time
debating a proposed bike shed than a
proposed nuclear power plant.&lt;/p&gt;
&lt;p&gt;&lt;a name="ref-4"&gt;&lt;/a&gt;&lt;span&gt;[4]&lt;/span&gt;
The 5 Whys approach was developed at Toyota by Sakichi Toyoda. Eric
Ries, author of &lt;a
href="http://www.amazon.com/Lean-Startup-Entrepreneurs-Continuous-Innovation/dp/0307887898/"&gt;The
Lean Startup&lt;/a&gt;, also recommends this approach for start-ups. He also
describes the approach in a &lt;a
href="https://hbr.org/2010/04/the-five-whys-for-startups"&gt;Harvard
Business Review article.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a name="ref-5"&gt;&lt;/a&gt;&lt;span&gt;[5]&lt;/span&gt;
Bridgewater Associates, one of the most successful hedge funds
of all time, applies the diagnosis process to all business problems,
not just software development. &amp;quot;Don’t depersonalize mistakes&amp;quot; is
Principle #15 in the company's guiding &lt;a
href="http://www.bwater.com/Uploads/FileManager/Principles/Bridgewater-Associates-Ray-Dalio-Principles.pdf"&gt;Principles&lt;/a&gt;.
The
founder, Ray Dalio, believes that the root
cause is always what people are like: their personality,
strengths, and weaknesses.&lt;/p&gt;
&lt;p&gt;&lt;a name="ref-6"&gt;&lt;/a&gt;&lt;span&gt;[6]&lt;/span&gt;
&lt;a
href="https://www.cs.utexas.edu/users/EWD/transcriptions/EWD03xx/EWD303.html"&gt;On
the reliability of programs,&lt;/a&gt; a lecture by
Edsger Dijkstra. Dijkstra, who passed away in 2002, is a Turing Award
recipient. The Turing Award is the computing equivalent of the Nobel Prize.&lt;/p&gt;
&lt;p&gt;&lt;a name="ref-7"&gt;&lt;/a&gt;&lt;span&gt;[7]&lt;/span&gt;
&lt;a
href="http://blog.ninlabs.com/2013/01/programmer-interrupted/"&gt;Programmer
Interrupted&lt;/a&gt;. An approachable blog post by researcher Chris Parnin
reviewing the academic research on programmer interruptions.&lt;/p&gt;
&lt;p&gt;&lt;a name="ref-8"&gt;&lt;/a&gt;&lt;span&gt;[8]&lt;/span&gt;
&lt;a
href="http://developermedia.com/developer-personalities-audience-brief-report/"&gt;Developer
Personalities: Audience Brief&lt;/a&gt;. Developers might also tend toward
Introversion (vs. Extroversion) and Thinking (vs. Sensing). Developers
who lean toward Sensing may have problems seeing the big picture.&lt;/p&gt;
&lt;p&gt;&lt;a name="ref-9"&gt;&lt;/a&gt;&lt;span&gt;[9]&lt;/span&gt;
&lt;a
href="http://www.intent-conference.de/DWD/_621/upload/media_1878.pdf"&gt;
Knowing Entrepreneurial Personalities - A Prerequisite for
Entrepreneurial Education&lt;/a&gt;. Unlike Entreprenuers, managers tend to lean
toward Judging (structure and decisions). A major implication of this difference
is
that the best person to start a company or project may not be the best person to
manage its day-to-day operations.&lt;/p&gt;
</content><category term="Software Engineering"></category><category term="software development"></category><category term="software engineering"></category></entry><entry><title>Combating information failure during software development</title><link href="https://toddschiller.com/blog/information-failure-software-development.html" rel="alternate"></link><published>2015-02-16T00:00:00-05:00</published><updated>2015-02-16T00:00:00-05:00</updated><author><name>Todd Schiller</name></author><id>tag:toddschiller.com,2015-02-16:/blog/information-failure-software-development.html</id><summary type="html">&lt;p&gt;Developer productivity is a product of program understanding,
a developer's (1) mental model, and (2) access to information for
refining that model.&lt;/p&gt;
&lt;p&gt;Former Defense Secretary Donald Rumsfeld's famous intuition is
actually roughly correct for understanding program understanding:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are known knowns. These are things we know that we know. There …&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;p&gt;Developer productivity is a product of program understanding,
a developer's (1) mental model, and (2) access to information for
refining that model.&lt;/p&gt;
&lt;p&gt;Former Defense Secretary Donald Rumsfeld's famous intuition is
actually roughly correct for understanding program understanding:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are known knowns. These are things we know that we know. There
are known unknowns. That is to say, there are things that we know we
don't know. But there are also unknown unknowns. There are things
we don't know we don't know.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Because software development involves constant decision-making, it's
also important to consider whether information is discoverable —
that we can, when required, make &amp;quot;known unknowns&amp;quot; become &amp;quot;known
knowns&amp;quot;. This yields three dimensions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Awareness:&lt;/strong&gt; does your (the developer's) mental model consider the
information?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Presence:&lt;/strong&gt; is the information present with the software (i.e., known)?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Computability:&lt;/strong&gt; can you compute and update the information
automatically (i.e., knowable)?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Across these dimensions, there are six situations that occur during
software development:&lt;/p&gt;
&lt;!-- markdownlint-disable MD060 --&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Aware?&lt;/th&gt;
&lt;th&gt;Present?&lt;/th&gt;
&lt;th&gt;Computable?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Unknown Unknowns&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Maybe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Uncomputable Information&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Stale / Misplaced Information&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Maybe&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Developer-Supplied Information&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Uncomputed Information&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Maybe&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Perfect Information&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- markdownlint-enable MD060 --&gt;
&lt;br/&gt;
In general, to increase the quality of information available,
you must supply additional information in the right form. The
information you supply signals intent, and can serve as
machine-checked documentation (with the right tools).
&lt;p&gt;The rest of this post describes the six situations, providing some
intuition behind their causes. It starts with Level 0, the most
dangerous level.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Level 0: Unknown Unknowns.&lt;/strong&gt; Properties of which the developer is
unaware. These typically occur when you have not anticipated a
use case, or do not understand a platform well enough to be
aware of potential issues. Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Thread-safety&lt;/li&gt;
&lt;li&gt;The (unintuitive) behavior of Javascript's operators&lt;/li&gt;
&lt;li&gt;Argument aliasing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;This is the worst situation to be in.&lt;/em&gt; If and when your software
crashes, your only hope is to re-create and observe &lt;em&gt;the effects&lt;/em&gt; of
the behavior. Because the behavior is not part of your mental model,
you won't know how to observe it directly.&lt;/p&gt;
&lt;p&gt;You eliminate &amp;quot;unknown unknowns&amp;quot; by expanding your awareness in two
ways: (1) experience, and (2) a broad exposure to software engineering
topics and frameworks. For most types of software, &lt;em&gt;your mental model doesn't
need to be
complete!&lt;/em&gt; You just need to be aware of potential &amp;quot;gotchas&amp;quot; so that
you can direct your development and debugging.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Level 1: Uncomputable Information.&lt;/strong&gt; Properties of which the developer is
aware, but does
not have an easy way of deciding automatically. Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The correctness of a sorting algorithm implementation&lt;/li&gt;
&lt;li&gt;Program termination&lt;/li&gt;
&lt;li&gt;How clients use your library&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Level 2: Stale / Misplaced Information.&lt;/strong&gt; Information that either might be
out-of-date
or is not present with the development artifact. Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Design decisions made by a developer who was fired&lt;/li&gt;
&lt;li&gt;Documentation for an old version of an API&lt;/li&gt;
&lt;li&gt;Requirements captured in an email thread&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have no way of telling which information is accurate, you're
back at &amp;quot;Level 1: Uncomputable Information&amp;quot;. If you have no way of
telling if the information is complete, you're back at &amp;quot;Level 0:
Unknown Unknowns&amp;quot;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Level 3: Developer-Supplied Information.&lt;/strong&gt; Information that is
up-to-date, but the developer has no easy way of knowing how a
change might affect that information. Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A written proof of an algorithm&lt;/li&gt;
&lt;li&gt;Class documentation&lt;/li&gt;
&lt;li&gt;Renaming a field in a dynamically-typed program&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you don't update this information when making a change, you'll
quickly find yourself at &amp;quot;Level 2: Stale Information&amp;quot;. By instead
capturing information in a machine-readable form, you can instead
approach &amp;quot;Level 4: Uncomputed Information&amp;quot;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Level 4: Uncomputed Information.&lt;/strong&gt; Information that can be computed
automatically, but is
not yet available for the current version of the program. Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Non-incremental compilation (e.g., compiling a C++ program)&lt;/li&gt;
&lt;li&gt;A long-running test suite&lt;/li&gt;
&lt;li&gt;A long-running static analysis&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When a failure occurs, you might be back at &amp;quot;Level 3:
Developer-Supplied Information&amp;quot; or &amp;quot;Level 2: Stale / Misplaced
Information&amp;quot;. For example, if a test fails, you need to be able to
determine (1) if the failure is valid, and (2) if so, how to modify
the program and/or test suite.&lt;/p&gt;
&lt;p&gt;For many types of information, you can effectively bring yourself to
&amp;quot;Level 5: Perfect Information&amp;quot; by applying the
&lt;a href="https://en.wikipedia.org/wiki/Pareto_principle"&gt;Pareto principle&lt;/a&gt;. In
the case of a long-running test suite, for example, you might
&lt;a href="http://digitalcommons.unl.edu/cgi/viewcontent.cgi?article=1018&amp;amp;context=csearticles"&gt;prioritize the execution order of the test suite&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Level 5: Perfect Information.&lt;/strong&gt; Information that is up-to-date and is updated
automatically whenever the developer makes a change. Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Incremental compilation with type checking&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Continuous_test-driven_development"&gt;Continuous testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cs.washington.edu/node/4042"&gt;Speculative analyses&lt;/a&gt; that
compute the effects of a change before you even make the change&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Remember that to increase the quality of information available, you
must supply additional information. For example, typed languages
require type annotations; more-detailed type analyses (e.g., the
&lt;a href="http://checkerframework.org"&gt;Checker Framework&lt;/a&gt;) require yet more
(and more precise) annotations.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;Program understanding depends on information awareness, presence, and
computability. The next time you hit a wall programming or debugging,
take a step back and ask: &amp;quot;where is the information failure?&amp;quot; By
answering this question, you can set yourself and your team up to be more
productive.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This post is based on an early framing of my PhD research. As part of
my research, I designed the &lt;a href="http://cupidplugin.com"&gt;Cupid framework&lt;/a&gt;
for giving developers immediate insight into their project and team.&lt;/em&gt;&lt;/p&gt;
&lt;style scoped&gt;
	.entry-content table {
		width: 600px;
	}
	.entry-content th {
		border: 1px solid;
		padding: 5px;
	}

	.entry-content td {
		border: 1px solid;
		padding: 5px;
	}

	blockquote p {
		font-size: 1em;
	}
&lt;/style&gt;
</content><category term="Software Engineering"></category><category term="information"></category><category term="mental model"></category><category term="software development"></category></entry></feed>