tag:blogger.com,1999:blog-46326195004919607882024-03-08T10:56:17.487-05:00Software on the BrainOn leadership, software and being human...Joseph Lynchhttp://www.blogger.com/profile/11886779384421780164noreply@blogger.comBlogger10125tag:blogger.com,1999:blog-4632619500491960788.post-26839559780894259652023-05-06T12:43:00.001-04:002023-05-06T12:43:48.881-04:00Sometimes the problem is to discover what the problem is (part 1)<p> "Sometimes the problem is to discover what the problem is." (Gordon Glegg, <a href="https://www.amazon.com/Design-Cambridge-Engineering/dp/0521074479" rel="" target="_blank">The Design of Design</a>, 1969)</p><p>As software engineers, we often frame problems poorly. Sometimes we frame problems in a way that is inflexible, overly-literal, convenient, laden with implicit assumptions or just plain wrong. The financial impact of this can be enormous: undertaking the "critical" re-platforming project that never finishes, grinds the business to a halt and causes a company to lose faith in its engineering organization; building features that are well-intended but barely used or even worse, ripped out, because they were poorly conceived; reduced time-to-market and revenue for those capabilities that are needed; and finally, we drastically reduce our potential effectiveness as problem solvers and most of the time we don't even realize it. Like high blood pressure, poor problem-framing can be the silent killer when developing software: it can destroy value delivery and we often don't even know it's a problem. <a href="https://en.wikipedia.org/wiki/Rich_Hickey" target="_blank">Rich Hickey</a> makes <a href="https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/HammockDrivenDev.md" target="_blank">the point</a> succinctly: "without a doubt, most of the big problems we have with software are problems of misconception".</p><p>Generally the later it is in the development lifecycle the more expensive it is to fix something. For example, fixing a bug in production is more expensive than fixing it at design-time. Makes sense. But it might surprise you how much more expensive it is. Is it twice as large? The late <a href="https://en.wikipedia.org/wiki/Barry_Boehm" target="_blank">Barry Boehm</a> researched <a href="https://www.unf.edu/~ncoulter/cen6070/handouts/minorreport/Boehm.pdf" target="_blank">this topic</a> and here's what he found:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6Ygi1goAKoq1EcYrGqOYj8_F9jXHIpeSBVryTGX9MHqvm9tue6hDYtuVw39Uq5XvPiLkAWHaqKmouGElk6av2l99An_KuMS4tbxgeSk1AXTG9J5UG18ipMqafPiS1zmgtBP79lD6BlmHbvaK9tF11Ntpotdxp1DNrpozQbvpgUyns2pbVkwqSRb9iIA/s814/slide_2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="517" data-original-width="814" height="406" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6Ygi1goAKoq1EcYrGqOYj8_F9jXHIpeSBVryTGX9MHqvm9tue6hDYtuVw39Uq5XvPiLkAWHaqKmouGElk6av2l99An_KuMS4tbxgeSk1AXTG9J5UG18ipMqafPiS1zmgtBP79lD6BlmHbvaK9tF11Ntpotdxp1DNrpozQbvpgUyns2pbVkwqSRb9iIA/w640-h406/slide_2.jpg" width="640" /></a></div><p>Finding and fixing a software problem after delivery is often <i>5 to 100 times</i> more expensive than finding and fixing it during the requirements and design phase. This is based on two publications from 1987 and 2001. But should you agilistas draw your swords, agile development does <i>not</i> fix this problem. Incremental delivery can lessen its impact but blind worship at the YAGNI altar and de-emphasis of the importance of design (whether intended or not) can worsen it too. Incremental delivery helps (so today's number is likely < 100) but that does not negate the overall premise here: <i>the later we fix a problem the more expensive it is to fix</i>.</p><p>Do you see the point? <i>The point of the lifecycle where we have the most economic leverage is when we are framing the problem -- and that is the point where we often make some of our biggest mistakes!</i> The impact of getting better at problem-framing can be enormous.</p><p>But what drives our tendency to frame problems poorly? What should we do differently? Great questions. Stay tuned for the next part of this multi-part series. </p>Joseph Lynchhttp://www.blogger.com/profile/11886779384421780164noreply@blogger.com0tag:blogger.com,1999:blog-4632619500491960788.post-48366277664052617752022-03-16T14:29:00.000-04:002022-03-16T14:29:01.038-04:00Who Are You Growing?<p>Who are you growing? It's important for leaders to ask themselves this question regularly. And if the answer is "I'm not sure" it's time to get busy. Building up your leadership bench is among the most important things you can do. And you don't need to manage people to be a leader. Are you a Tech Lead or someone that has a strong influence across your organization? If so, you're a leader. Read on.</p><p></p><div>Leadership development isn't a luxury. It's a necessary risk reduction technique for your business, one of the basic facets of succession planning. For every leader in your organization (that includes VPs, Directors, Managers, Tech Leads, etc.) it's ideal to have someone that could step into their shoes (with support), ideally someone they have been grooming for some time. Key leaders will depart the organization or move on to other roles. They're in high demand and have no shortage of opportunities. It's not a matter of *if*, it's a matter of *when*. The departure of a high-impact leader without a plan for quick recovery can turn an organization into a tailspin.</div><div><br /></div><div>Meh. We can just find a replacement! Sure. Welcome to the life of an executive recruiter. There are about 1/10 the number of managers as there are IC engineers so the pie is small from the start. Directors are more rare than managers. VPs more so. And, sadly, many are ineffective (manager horror stories anyone?). The best ones aren't looking and are hard to engage. (And you only want the best, right?) If you're lucky enough to get their attention they then have to get through your simple, 37-step interview process where you ask them to estimate the number of Starbucks stores in Manhattan, reverse a linked list, design Google Maps at a virtual whiteboard they've never used before, convey executive presence in a video conference with their dogs barking in the background, tell you about a time when they demonstrated customer obsession while cutting costs, do a take-home assignment and then be excited about joining your company for a smaller role with less pay because you're changing the world through platform-enabled AI-driven workflow-based autonomous microservices powered by the latest in blockchain technology. (It's going to be huge!) Meanwhile your competitors are banging down their door and they're fairly happy where they are. And then, when you can't put your finger on why they don't "feel" right (hiring a leader is scary so people use their gut more than they admit), you stumble upon some other "minimum qualifications" that you didn't include in the job description. After all it should be obvious that you want someone "seasoned" who has done this 2 or 3 times, has 13+ years of FAANG experience, knows how to step into an existing team with no context, boost morale, set a vision and strategy, recruit great people, build credibility, be able to talk about distributed consensus protocols, understand your tech stack, jump into the code if need be, build relationships, call bullshit on a technical decision and yet somehow not get too involved all while being a "cultural fit" which is code for "supporting the un-stated values and practices that we aren't willing to put into writing (because then we'd admit that they're real) that can only be discovered by violating them". It's easy! Finally, when the leader joins nobody will trust them yet and there's a decent chance they'll turn things upside down and piss everyone off in the process. :-) Bringing in external leaders is important and necessary to expand the thinking of an organization. But it takes a long time and the risk has to be properly managed. It's best done strategically and not reactively.</div><div><br /></div><div>More than just a risk-reduction technique, growing leaders is also one of the best ways to build up the capability of your organization and your company. It demonstrates foresight and commitment. You're thinking like an owner. It's great for the leaders that you develop - they are exposed to new opportunities and they can stretch themselves, but in a setting where you can provide proactive support. Your teams can see that good work exposes people to new opportunities and that managers aren't (solely) plotting how to take over the world in the back room while smoking cigars and laughing like Dr. Evil. And if you successfully reach the "payback period", you will have improved the effectiveness of your organization. You've engineered yourself into redundancy, which is actually a good thing. It may be time to take on a new challenge. Finally, there is one more benefit: it feels good. As leaders we often do tiny things all day and wonder whether we're making a difference. Seeing someone progress quickly, someone that you admire, someone that you learn from through teaching them, someone that's grateful that you're looking out for them - that's a great feeling.</div><div><br /></div><div>So why don't we do it more proactively? We're busy. There's always going to be something more urgent. It takes a while to pay off (months, sometimes years). All these things are true but we have to remind ourselves that it's strategic, it's essential for the business and for your organization, it's a way to create a multiplicative influence - and when you step back and see someone get closer to realizing their potential and to know that you played a part, even a small part, in making that happen -- it can be rewarding beyond compare.</div><div><br /></div><div>So -- who are you growing?</div><p></p>Joseph Lynchhttp://www.blogger.com/profile/11886779384421780164noreply@blogger.com0tag:blogger.com,1999:blog-4632619500491960788.post-6540022079119405672022-01-22T16:48:00.001-05:002022-01-22T16:57:49.795-05:00The Misunderstood Single Responsibility Principle<p>The <a href="https://en.wikipedia.org/wiki/Single-responsibility_principle" target="_blank">Single Responsibility Principle</a> (SRP) is the first of the <a href="https://en.wikipedia.org/wiki/SOLID" target="_blank">SOLID</a> design principles that have been highly influential in software engineering since they were introduced by <a href="https://en.wikipedia.org/wiki/Robert_C._Martin" target="_blank">Robert Martin</a> ("Uncle Bob") in 2000. Unfortunately, this particular principle is often misunderstood. When coupled with blind faith this can engender overly simplistic thinking and design mistakes.</p><p>The principle has often been <a href="https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html" target="_blank">framed</a> as "each software module should have one and only one reason to change". And then the name seems to suggest that the module should have a "single responsibility". That seems pretty easy to understand. So the module should only do one thing, right? <i>No</i>. There's a different rule of thumb around that: a <i>function </i>should only do one thing. Have you ever held your nose while naming a function something like "ImportData<i>And</i>LoadIntoDatabase". We know this: a function should have a single, well, <i>function</i>.</p><p><i>The SRP is a license to sometimes forgive yourself for what feels like breaking <a href="https://en.wikipedia.org/wiki/Cohesion_(computer_science)" target="_blank">cohesion</a>. </i>The principle actually means that the code in a given module has to be owned by one and only one ultimate business owner (or functional unit). If that isn't true you have to break it up. Uncle Bob uses an example (in <a href="https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html" target="_blank">writing</a> and <a href="https://youtu.be/zHiWqnTWsn4?t=3152" target="_blank">talks</a>) where the CFO and COO both depend on the code that calculates employee hours. Calculating hours is simple math that everyone should agree on, right? One executive requests a change to that code and it breaks the other's business rule. The hours calculation cannot be shared: that piece of code should have a Finance version and an Operations version, despite the fact that that violates our <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself" target="_blank">DRY</a> and cohesion sensibilities. This is <i>very different</i> than the way I have seen most people apply the SRP.</p><p>While I don't need to apply it everyday, the SRP does align with my experience. I worked on a Transportation Management System and we had an object that represented truck movements. It was operational in nature - you'd assign a driver, arrival and departure times for shipping locations, etc. There was another version of that object that was used for paying the drivers. The objects were one-to-one with a lot of apparent duplication. It really drove me crazy! Several times I tried to treat them uniformly with the same code and it inevitably failed. And guess what? One object belonged to Operations and one belonged to (you guessed it) Finance. <i>It was the exact thing that Uncle Bob was talking about.</i> While the SRP is true, it's sometimes hard to apply proactively as who (or which group) is the "ultimate owner" of something can be squishy and take time to become clear, especially if you're building a system from scratch with many stakeholders. From another angle, I see the SRP as a natural consequence of <a href="https://en.wikipedia.org/wiki/Domain-driven_design" target="_blank">DDD</a> principles: it's unsafe to have a model that is shared across <a href="https://martinfowler.com/bliki/BoundedContext.html" target="_blank">bounded contexts</a>.</p><p>Unfortunately, I've seen many people follow the incorrect understanding of the SRP with blind faith. Often people who like tiny classes will use it to justify making many more even tinier classes. What starts as a simple, easy-to-understand class ends up being broken into many abstractions that are now harder to understand collectively. Regardless of whether you like that style, the SRP on its own will not drive you there. I recently read <a href="https://www.amazon.com/Adaptive-Code-principles-Developer-Practices/dp/1509302581" target="_blank">Adaptive Code</a> (2nd Edition, Microsoft Press) which, as of today, has a 4.7/5 rating on Amazon with 123 ratings. There is a whole chapter on the SRP. And throughout, it incorrectly explains the SRP as relating to classes doing too many things and justifies design decisions based on that alone. For cohesion reasons, classes shouldn't do too many things; so the design decisions aren't always bad. But, as an example, a class with 2 pages of code is broken into ~12 classes and interfaces, all in the name of the misunderstood SRP. And this is a well-respected book by an an accomplished author, not some random blog post.</p><p>We have to encourage emerging engineers to understand the reasoning behind these principles, to wrestle with them, to apply them when they make sense and reject them when they don't. It's also instructive and fascinating to go back to the sources. The SOLID principles are rooted in core design principles that pre-date our generation -- like the <a href="https://en.wikipedia.org/wiki/David_Parnas" target="_blank">Parnas</a> <a href="https://www.win.tue.nl/~wstomv/edu/2ip30/references/criteria_for_modularization.pdf" target="_blank">paper</a> that introduces the idea of <a href="https://en.wikipedia.org/wiki/Information_hiding" target="_blank">information-hiding</a> and the <a href="https://www.amazon.com/Structured-Design-Fundamentals-Discipline-Computer/dp/0138544719" target="_blank">book</a> where <a href="https://en.wikipedia.org/wiki/Larry_Constantine" target="_blank">Constantine</a> introduces the ideas of <a href="https://en.wikipedia.org/wiki/Coupling_(computer_programming)" target="_blank">coupling</a> and <a href="https://en.wikipedia.org/wiki/Cohesion_(computer_science)" target="_blank">cohesion</a>. Uncle Bob credits these works with influencing his thinking. In his talks, usually after his requisite, random physics ramblings, he always makes an effort to connect the present with the past. That's a great thing. But there aren't many Uncle Bobs around. As an industry, we don't do a good job of passing down experience across generations. What can we do about that? While it's an exaggeration to say that "there is nothing new under the sun", it's amazing how often we wrestle with old problems and are unaware that we can stand on the shoulders of those that came before us.</p><p>Why do we as engineers like these design principles? (I know I do.) Aside from their heuristic utility, I think it's because they provide what feel like constraints for what would otherwise be an unbounded solution space. They reduce anxiety and introduce some semblance of determinism where none can be found. Ordinarily we're a rebellious lot and hate constraints (tell someone they <i>must</i> use vim or emacs). But constraints are our friend when we're facing the abyss of an open-ended problem so we reach for them. But we sometimes reach too far. Experience-based observations become principles, which become rules of thumb, which become rules proper that, finally, ossify into law. But let's be careful here. Physics aside, the only absolute law I've found in Software Engineering is that there are no laws to be found. After all, we're building castles out of bits.</p>Joseph Lynchhttp://www.blogger.com/profile/11886779384421780164noreply@blogger.com16tag:blogger.com,1999:blog-4632619500491960788.post-18885123936520496762021-12-03T11:41:00.051-05:002021-12-03T19:29:35.749-05:00Having Career Conversations<p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">“What’s your 3-5 year plan? Where do you see yourself in a few years? What do you want to accomplish?” Unless you’re in a massively trusting setting (e.g. a spouse or best friend), who wants to answer these kinds of questions? You might feel put on the spot. You might feel ashamed at not having an answer or that the answer might somehow be graded. Am I ambitious enough? Am I humble enough? Is it ok to say “If it were open I’d like to have your job”? Is it ok to say I want to start my own business even though that may imply leaving the company? Stumbling for an answer you might mutter a platitude such as “I see myself seeking gradually increasing levels of responsibility while maximizing my positive impact on the dynamics of the business...” (zzzz) So on the receiving end, we see these conversations as challenging. When we ask these questions of those that we mentor or manage is it any wonder that they don’t always go so well?</span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><br /></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">What is the desired outcome of exploratory discussions related to someone’s career development? A good outcome should (eventually) include:</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"></p><ul style="text-align: left;"><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Goal(s)</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">An understanding of the motivations that underlie the goal(s)</span></span></li></ul><p></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">I have often found that it is tempting but dangerous to focus only on #1. “I want to be a Tech Lead within 5 years”. “Check - we’re done! That was easy. Great discussion.” The problem is that we don’t know what is motivating the goal. It can be a tricky a combination of such factors as:</span></span></p><p style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: left;"></p><ul style="text-align: left;"><li><span style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">Desire to influence</span></li><li><span style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">Desire for authority</span></li><li><span style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">Desire for prestige / acknowledgement / appreciation / status</span></li><li><span style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">Desire for growth & mastery</span></li><li><span style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">Desire for autonomy</span></li><li><span style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">Desire to do something meaningful</span></li><li><span style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">Compensation</span></li><li><span style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">Guessing (just pick the next rung on the ladder!) :-)</span></li></ul><p></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Picking the next rung on the ladder may work fine for a time, especially if one is new to the ecosystem. Do good work, enjoy it, get more responsibility and iterate. But the algorithm may eventually break down and may take some time, pain and mistakes before the realization that it’s time to chart a new course. Understanding what lies beneath our goals affords us the option of making more strategic choices.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><br /></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">But how do we get the desired outcome of goals and motivations? If it were easy we’d all download the app and be done with it. But it’s not easy and what works for one mentor/mentee combination might not work for the next. Nevertheless there are some essential ingredients the absence of which will make for a bad meal:</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"></p><ul style="text-align: left;"><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">The mentee must trust the mentor. The mentee has to have confidence that the mentor will not use the information against them or push them into a path that is not necessarily in their best interest. Such trust takes time and patience to build.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">The mentor must trust the mentee to some degree. The mentor has to have the confidence to brainstorm, share anecdotes and be frank in discussions. And as noted above trust takes time.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">There must be mutual agreement on how discussions will be treated with respect to confidentiality. For example, the mentee’s manager will have limits on what can be kept fully confidential whereas a more informal mentor might not.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Trust facilitates openness and honesty. Add in some hard work and there’s a very good chance that the process will yield fruit.</span></span></li></ul><p></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;"><br /></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">But what is “the process” and how do we go about this concretely? There is no one right way to do this and the best process will likely be a function of the mentor/mentee combination as well as cultural and organizational dynamics. And we won’t employ the “best process” because we’re human and will make mistakes. We will learn from trial and error. What’s most important is that we learn and consider career coaching to be a foundational part of our job.</span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;"><br /></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">Some concrete suggestions to consider:</span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"></p><ul style="text-align: left;"><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Focus first on building mutual trust. The first step in this is forming a relationship which will create opportunities for trust to be built up incrementally.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Try to be explicit about expectations up front including roles, logistics, level of confidentiality, etc.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">One way to build trust is to be vulnerable. Share personal anecdotes especially those that are embarrassing and induce a good belly laugh. It sends the message that we’re all human and make mistakes.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Be mindful of other things that build trust like keeping your commitments and apologizing when you make a mistake.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Accept that there are limits to trust that may be specific to the mentee and beyond your control.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Accept that there are limits to trust based on cultural and organizational factors. For example, the mentee’s manager should always help with career coaching. But some people might need additional mentor(s) outside their reporting chain to feel completely comfortable. It is perfectly normal for a mentee to seek multiple mentors.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Try to remove any shame or embarrassment attached to having lofty financial goals. Such goals are often tied up with a sense of safety, well-being, supporting a family or earning enough money to fulfill a lifelong dream. In addition, compensation growth can be important in order to feel valued and appreciated. To some it is also a concrete measurement of growth.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Try to remove any shame or embarrassment attached to having career goals that would be best fulfilled in a different part of the organization or outside the organization altogether.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Try to remove any shame or embarrassment attached to being ambitious. What if they want your job? Or your boss’s job? Ask the mentee the following question: “Imagine everyone in the company (except you) won the lottery and on the same day decided to resign to spend time with their family and friends. Whose job would you want and why? Whose job wouldn’t you want and why?”</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">If they can answer the question above, ask what they think the job would entail. This can help illuminate whether they’re reading the organization accurately.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">When trying to get to underlying motivations keep trying to get to “why” (perhaps in a subtle way) until you hit bedrock. Bedrock is not “I want to be a Tech Lead” but things like “I love working on the hardest problems because it keeps me from getting bored” or “I love helping people”. Bedrock statements tend to be about our core needs, beliefs or interests. They’re often very simple. They don’t tend to be industry-specific or job-specific and they don’t change overnight.</span></span></li><li><span style="font-family: Arial; font-size: 14.6667px; white-space: pre-wrap;">Try to tease out desires for influence and desires for authority. They are not always mutually exclusive. Some combinations can be rooted in a desire for impact. Other combinations can be rooted in a desire for control.</span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Try to uncover passions. The mentee may or may not be able to connect their work back to their passions. If someone can’t identify their passions, observe their tone when they talk about different things in relaxed or social settings. People tend to get excited about or want to talk about things that tie back to their passions. Passions are often driven from values and purpose.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">When trying to uncover passions, point out the fact that doing so is a win-win if you’re their manager. “If we can get you working on something you're passionate about, I can be more effective as a manager.”</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Look for the overlap between interests (passions are basically strong interests), strengths and the needs of the company - this is the sweet spot for growth within the company. But don’t forget to allow for the possibility that their interests may be best served outside the company.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Refrain from judging the fitness of their interests or goals.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Don’t advise unless explicitly asked to and even then consider whether you should. Be transparent that you’re trying to refrain from advice. (This is very difficult for those of us who love solving problems!) Listen intently, play things back, confirm things, ask provocative questions, expose underlying assumptions, etc. Listen much more than you speak. Generally you are trying to help them come to their own conclusions, not reach conclusions on their behalf.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Integrate career discussions into daily work over time. If you are their manager, seek assignments and opportunities for the mentee that reflect your support of these goals. Make sure the mentee sees that you understand their career goals and are mindful of them.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Experiment and leave room for error. They may come to and act on a conclusion that turns out to be wrong. For example if someone wants to be a tech lead they might try to lead a small project effort. After leading that effort they might reach the conclusion that they were way off! Perhaps they like owning a slice of functionality as a senior developer but trying to influence others without authority is not their cup of tea.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Talk to others that mentor and manage people. Share ideas and experiences with one another. Write them down. Contribute to the collective wisdom.</span></span></li><li><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Be patient and persistent. This is not a single conversation. Rather it’s a conversational theme that you’ll have to chip away at over time and it may involve receiving and passing the torch to other mentors. Don’t think days or weeks. Think months or years.</span></span></li></ul><p></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><br /></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;">Wow! That sounds like a lot of work. Why are we doing this again? Because great people will be nurtured or will find new homes. Because career coaching is an essential component of engaging the best and brightest. And because the quality of its people is the foundation of an organization's success.</span></span></p>Joseph Lynchhttp://www.blogger.com/profile/11886779384421780164noreply@blogger.com0tag:blogger.com,1999:blog-4632619500491960788.post-18720294777393664232020-08-29T12:57:00.000-04:002020-08-29T12:57:49.928-04:00Note to Self: All Feedback Is a Gift; and It's All Accurate<span style="font-size: x-small;"><i>The "you" and "I" in the post are both me (yes, I'm talking to myself). </i><i>Note that, in this post, the term "feedback" denotes constructive criticism only. I also exclude from consideration cases where the person giving the feedback is deliberately lying or where critical aspects of the feedback are built upon presumed facts that are demonstrably incorrect.</i></span><div><div><i><br /></i></div><div>
<br /><div>Remember that:</div><div><ul><li><b>All feedback is a gift</b>. Imagine feedback to be a stated observation regarding a non-deterministic system that is essential for you to get anything done; but the system has no documentation, no source code, no unit tests and thus no ability to be upgraded. In order to understand the system, all you can do is create a set of conditions, perform an operation using some input and observe the system's non-deterministic response. Whenever you uncover problems in the system's behavior that you think will happen again, you devise workarounds. But you don't always remember them or apply them correctly; besides, the system behavior is changing without you knowing. Will the workarounds even work today? Understanding this system and using it to get things done would be a hard job. If someone reported a new potential bug for that system, would you be angry with them? Or would you treat it like gold?</li><li><b>All feedback is accurate</b>: it's accurate that it is their stated <i>perception</i>.</li></ul></div></div><div><br /></div><div>When someone gives you feedback, apply the following algorithm:<div><ul style="text-align: left;"><li>Take some deep breaths, listen and be curious. Try to reflect that in your body language as soon as you can - you're curious only. It may take 30 seconds or so to consciously put yourself in that state. You can sometimes buy yourself time by just saying "hmm...let me think about this" with a Sherlock Holmes face. Why do this? Because unless you're devoid of emotion (i.e. not human) you will likely have a quick negative reaction even if you don't verbalize it. At worst, you may be subjected to a mini <a href="https://www.alchemyassistant.com/topics/PaT4j2YKrTSMGkN5.html" target="_blank">emotional hijacking</a> where emotions (anger, defensiveness) supersede logic in response to a perceived threat (criticism perceived as attack). You want to get out of that and consciously move to curiosity, by enabling transfer of control from the emotional decision-making center in your brain to the logical decision-making center of your brain. The best way to do that is to provide additional time for your brain to re-process the stimulus.</li><li>To what may this be compared? Imagine you're taking a walk in a field. All of a sudden, out of the corner of your eye, you notice a thin, long, dark, crooked object 2 feet away from you. A snake!! Your immediate response is existential fear which causes the release of stress hormones, telling you to jump back and protect yourself. Within about two seconds you see it's a stick and laugh at yourself. But if you notice, you feel pressure in your chest, your breathing has quickened, your heart rate has escalated, your blood pressure is through the roof and you certainly have an unpleasant look on your face. You do not always perceive feedback this way, but the closer it feels to an attack the more you do so. And your ability to be emotionally self-aware in such a situation is limited. That's why it's important to give yourself time to move from an emotional response to a reason-based response, just as you needed in the situation of the snake.</li><li>Fight the urge to debate the issue or provide justification/excuses for the behavior or output (e.g. a presentation) they may be criticizing. This urge is almost always there. Swallow it.</li><li>Even if it feels unnatural, say something along the lines of "Thanks for the feedback. I know it's not easy to be transparent and I really appreciate it." You will actually feel the truth of this statement if you give yourself time and if you are honest with yourself.</li><li>If you have questions of a <i>clarifying nature only</i>, say "Do you mind if I ask some clarifying questions? I want to make sure I understand your perspective properly". Asking questions that are thinly-veiled attempts to get them to see the lack of validity of their criticism are not clarifying questions. Avoid all questions and statements that suggest you may consider the feedback to be potentially invalid or useless.</li><li>Let's say the feedback is "I feel like you're kind of disrespectful in the way you communicate". This is not a silly example. Some clarifying questions:</li><ul><li>Do you mean in email, documents, IM, face-to-face communications?</li><li>Do you mean in work settings? Out of work settings? (e.g. drinks with the team after work)</li><li>Do you mean just with you, just with other specific people, in group settings?</li><li>Is it all the time? Most of the time? Often? Sometimes?</li><li>What are some recent examples? And when they say they can't remember, which is a common response, see if you can seed their memory and encourage further transparency by calling out potential examples. "In that recent team meeting I know I was hammering home the point that I really think we should do X despite the fact that so and so said we should do Y? They rolled their eyes. Is that an example?"</li></ul><li>Once you've clarified, restate the newly-codified feedback statement to them and see if they agree that it's accurate. If not, keep iterating. Example restatement: "OK. So you're saying in group meetings, I discourage opinions that are different than my own, quickly trying to shut them down. I even go so far as to mock the person a bit. A recent example was when we were trying to decide whether to use the whigglewham library or the zipzorp library. I was clearly in favor of using whigglewham but when so-and-so advocated for zipzorp, not only did I cut the conversation short, I mocked them when I said sarcastically, 'Heh. And how long have you been on this team? You know how doorknobs work, right?' All communications aside from verbal communications in group meetings are respectful. Is that accurate?" Once you land on an agreed-upon statement of the feedback, your understanding of the feedback is likely to be far more precise and actionable.</li><li>Now you want to wrap up. If there is any doubt, don't acknowledge fault at this point. If there is obvious fault acknowledge it and offer any apology that is genuine. Except in the most obvious cases, avoid stating what your corrective actions are going to be (if any) because you likely need to think about that.<br /></li><li>End with "Again, thanks for the feedback. I appreciate the transparency and this is really helpful."</li></ul><div><br /></div><div>Now you begin the process of thinking through the feedback, whether to take any action and if so what that action should be. That's an exercise left to the reader.</div><div><br /></div><div><br /></div></div></div></div>Joseph Lynchhttp://www.blogger.com/profile/11886779384421780164noreply@blogger.com0tag:blogger.com,1999:blog-4632619500491960788.post-49135631222676974112016-04-06T16:52:00.001-04:002016-04-06T16:52:12.380-04:00A Conversation That Changed My LifeI usually post tech things on my blog but before being a technologist, I'm actually a human and occasionally experience something worth sharing. And so, an anecdote...<br /><br />In the fall of 2013 I found myself exploring new career opportunities. At the time, my network within the Philly community was fairly weak as I had worked in Princeton, NJ. I was targeting VP-level Technology opportunities in the Philly area but I had no idea where to start. I met a recruiter who had a position open. We met over coffee and it turned out I wasn't a fit. But he introduced me to a man that he used to work with whom he said "helps people out".<br /><br />This man didn't know me from Adam. But on fairly short notice he agreed to talk with me over the phone on a Friday evening. He had a long drive in front of him and we ended up talking for about an hour and a half. He listened to me and made me feel comfortable. He didn't tell me I was aiming too high like others did. He anticipated my needs. He talked to me about all kinds of things: networking groups, how to find opportunities and "paperwork", as he called it. Turns out he too was on the lookout for new opportunities but he only mentioned it in passing. He was commuting hundreds of miles each week for an out-of-state CIO position. He would spend the weekdays at work and then come home on the weekends. I tried to pin him down for a cup of coffee but he only suggested that maybe he'd swing by my town one day as he liked to drive along the Delaware river. At the end of the call he said he'd send me some stuff when he got home. A few hours later I received ~6 emails, each of which had zip files with several Megabytes worth of attachments that had been curated and collected from the internet - resumes, cover letters, recruiting firms, bonuses, stock options, negotiating comp. It looked like it was the result of ~3 months of active research. In the email trail I could see that he had forwarded these emails to dozens of people. All he did was re-send them from his Sent folder. Without prompting, he also introduced me to a few people over email, including his brother. (Who the hell introduces their brother to someone that they just met over the phone?) I had no idea what to make of this. I am naturally suspicious of people that want to "help" with no apparent motive. Over the coming months he introduced me to several other great contacts. And I managed to put him in touch with one or two people that might have a good job for him, in order to assuage my sense of guilt. Yes, guilt. I needed to repay him but how could I? He didn't seem to want anything in return.<br /><br />Since that time, I have become a more active networker. From his example the only trick I've learned when it comes to networking is to just try to help people. That's it. Nothing more, nothing less. Ask "How can I help?" and mean it. Since meeting him, I read a book called "Influence: The Psychology of Persuasion" by Cialdini. After reading it (in addition to feeling like an idiot for having bought an unsolicited meat freezer and half a cow from a salesman who took me for a ride) I started to understand my feelings. Built into our brains is the unwritten rule of reciprocity. Our society has functioned best when humans both give and take. But we don't like people that take exclusively and we sniff them out and shun them. I'll give you a hunk of meat around the campfire if I can expect that when I'm in a pinch you might give me a hunk of yours. Our biology has evolved this function to support the survival of the species. But this was different. This man was a <i>giver</i> and didn't look for anything in return - he gave away his meat without keeping tabs. My brain's instinct toward reciprocity caused me to want to pay it forward to others if I couldn't find a way to repay him directly. At least then my debits and credits would balance out. But I found out that it doesn't really work that way. Once I got used to (occasionally) helping people I found it rewarding. I got to play a small part in their success and to feel a tiny hint of meaning amidst the bustle of everyday work.<br /><br />I recently met him in person at a networking luncheon. I was so thrilled! I reminded him that he had helped me and that I was grateful. It rolled off him like water off the back of a duck. "That's great" he said and then moved on to something else. He was no master of social etiquette. The woman who led the group (a high priestess of networking herself) said "keep so-and-so in your thoughts as he's sick" and he blurted out "yeah - he has cancer!". He was promptly scolded (in good humor) by the group leader: "hey - we're trying to keep the details private!". I was looking forward to talking to him after the event but he darted out as soon as it was over. "Oh well - I'll get him next time" I thought.<br /><br />A few weeks ago I was scheduled to have coffee with his brother, the same one that he had introduced me to. He's another active networker that is generous with his time. He cancelled the day before. He learned that his brother had died suddenly that morning. In the email, sent on the day that he'd learned of his brother's unexpected passing, he suggested alternate dates when we could meet. I couldn't bring myself to re-schedule.<br /><br />I barely got a chance to say hello let alone a chance to say goodbye. But an hour and a half on the phone changed the way that I think about professional relationships. His name? His name was Joe Tait and I suspect that he helped hundreds of people the way that he helped me. Thanks, Joe. Still looking for a way to pay you back...<br /><br /><br /><br />Joseph Lynchhttp://www.blogger.com/profile/11886779384421780164noreply@blogger.com11tag:blogger.com,1999:blog-4632619500491960788.post-39450856710569117502015-07-24T09:22:00.001-04:002015-07-24T09:59:39.084-04:00Non-Production Environments: Anti-Patterns<h3>
Introduction</h3>
<h3>
</h3>
<h3>
</h3>
We all know that clean, separated environments are critical for developing and testing our software. And yet somehow we tend to get it wrong, often. The Continuous Delivery movement puts this at the forefront of its concerns, which is great. So if you're headed down the CD path, chances are you are tackling or are about to tackle the "environment problem". Because it's a tough thing to get right and because it involves up-front and continuous investment, it tends to be de-emphasized in the feature-crazed Agile world. But unless you're just doing a proof-of-concept, not solving the environment problem will slow you down, hurt quality and become harder to fix over time. There are a few anti-patterns that I see over and over:<br />
<ol>
<li>Not giving proper attention to the data tier(s) of the stack (e.g. relational database, NoSQL database, text/search database, file systems used for storage, etc.)</li>
<li>Not extending environments "all the way out". You should be able to have environments that go up and down: CDN->Load Balancer->Web Server->App Server(s)->DB Server(s), etc.</li>
<li>Assuming that the number of non-production environments that you need is fixed and can be predetermined.</li>
</ol>
So, let's talk a little about these a bit, one at a time...<br />
<br />
<h3>
Not giving proper attention to the data tier(s) of the stack</h3>
<h3>
</h3>
The reason this gets skimped on is because it's hard! Some issues:<br />
<ul>
<li>ORMs have encouraged ignorance of relational databases and people don't work hard at things they do not understand. If you don't understand a relational database, what are the chances you're going to work at getting a synch / replication / sub-setting process built? Most developers who have come up in the last 10 years have a small fraction of understanding of relational databases when compared to those who came up before that. Before ORMs, you had to understand relational databases in detail to build a complex application. ORMs have been both a blessing and a curse in some ways. Many would say only a curse. One of the "curse" aspects is that they encourage ignorance where ignorance is to our detriment. Despite the emergence of other data stores, relational databases will survive for many years for certain use cases. The ACID and strong consistency guarantees are very convenient for certain problems. If distributed ACID emerges (e.g. FoundationDb, NuoDb attempt this) then that could move some of those use cases away from the relational model. But most (balanced) experts agree that for the foreseeable future, relational databases remain an essential aspect of storage even as NoSQL takes over certain use cases. One notable exception is Michael Stonebraker, inventor of PostgreSQL, VoltDb, recent Turing award winner and certainly smarter man than me. He predicts that column stores will obviate relational databases within the data warehouse arena and that distributed ACID systems like VoltDb will take over what remains of their share in the OLTP market. However VoltDb is an in-memory database and he doesn't (as far as I can tell) talk about distributed ACID that's too big to fit in memory. That's what FoundationDb, etc. are trying to address. He is a guru but also extreme in his views. I agree that relational databases can (and perhaps will) be completely overtaken - but distributed ACID large-scale databases need to be built for that to happen. It's interesting to see that Google has moved away from BigTable and built a distributed ACID system for its developers. (Spanner, F1) Unfortunately it depends upon specialized hardware at the data center (atomic & GPS clocks) that is not yet available to the average consumer of the public cloud. Maybe CaaS (clocks as a service) will be added by AWS someday.</li>
<li>Increasingly, production systems are bigger and bigger. So having any production-like data means having to copy around TBs of data. To get it right you must often subset the data. Both dealing with TBs and sub-setting TBs is hard work. Sub-setting, for example, requires refinement and continuous maintenance as you add new types of data. You can't approach the problem generically.</li>
<li>Given the explosion of database options ("polyglot persistence") it's common to have disparate types of databases for different use cases. Each of these has to be well-understood to have good data environments. This brings complexity. For example, at LeadiD, we like Couchbase for a doc store and separately for a cache/key-value store, Elasticsearch for text/search and logging, PostgreSQL for relational, Azure and S3 for file storage, Kafka for messaging and Graphite for metrics. That's a lot of things to get right and we're fairly careful about bringing in another data store. </li>
</ul>
<h3>
</h3>
<h3>
Not extending environments "all the way out"</h3>
<h3>
</h3>
An environment should extend across all layers and tiers of a system. For example, the CDN tier, the load-balancer tier, web server tier, app server(s) tier, data tiers, etc. If you have access to a cloud infrastructure, this is fairly straightforward. It just takes foresight and discipline. With REST APIs for everything needed such as DNS management, CDN management, virtualization, Docker, etc., the tools are there to get this right. It requires discipline but is nowhere near as hard as getting the data stack right.<br />
<h3>
</h3>
<h3>
Assuming that the number of non production environments that you need is fixed</h3>
<h3>
</h3>
You cannot know the number of non-production environments you need in advance and yet people make the big mistake of hard-coding and only configuring 3-4 environments total (e.g. Dev/QA/UAT, Dev/QA/UAT/Staging, Dev/QA/Staging). There are two problems with this:<br />
<ol>
<li>You need one of these for every independent code path (e.g. might be a sub-team or a long-lived branch [sometimes you have no choice])</li>
<li>You need more than these for some code paths - and you can't always predict which ones you'll need. For example, it's common to have a "performance" environment that has enough data to tune nasty queries. It's common to have a "prod repro" environment that has a continually-upkept database (maybe nightly) to be able to reproduce transaction-specific bugs that were recently reported. There are environments to deal with automated testing, environments to practice data loads and environments for a particularly invasive feature a developer might be working on. You cannot predict the number of independent code paths. And you cannot predict the number of environments you'll need to function optimally along a given code path.</li>
</ol>
One manifestation of this cardinal sin is code (even if test code) that hard-codes understanding of fixed non-production environments or assumes that only certain of these exist. (e.g. "if (env == 'QA') then ...") This is bad. Ideally your <i>code</i> should be completely environment-agnostic. If your back's up against the wall you can code for detecting production vs. non-production. But that's it.<br />
<h3>
</h3>
<h3>
Outlook</h3>
<h3>
</h3>
While every setting I've worked in has had variations of these problems I have tried hard to at least deprecate these practices and make headway toward reversing them. But of course there is no such thing as true greenfield unless you're employee number 1. And if you're employee number 1 it's irresponsible to be spending this much time thinking about these things because who knows if you even have a product? And so it comes down to knowing up-front what best practices are, accepting that in the beginning you'll incur some tech debt but moving to good environment practices as soon as you can tell that you have a product. At LeadiD we have many of these problems just like anyone else. We're tackling them now as we embark upon the journey of Continuous Delivery. Fingers crossed...Joseph Lynchhttp://www.blogger.com/profile/11886779384421780164noreply@blogger.com0tag:blogger.com,1999:blog-4632619500491960788.post-91046610112627519932014-11-06T18:07:00.001-05:002014-11-06T18:07:34.812-05:00Dig a Little Deeper
<style>
<!--
/* Font Definitions */
@font-face
{font-family:"Courier New";
panose-1:2 7 3 9 2 2 5 2 4 4;
mso-font-charset:0;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 0 0 0 1 0;}
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;
mso-font-charset:2;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:0 268435456 0 0 -2147483648 0;}
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;
mso-font-charset:2;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:0 268435456 0 0 -2147483648 0;}
@font-face
{font-family:Garamond;
panose-1:2 2 4 4 3 3 1 1 8 3;
mso-font-charset:0;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 0 0 0 1 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-parent:"";
margin-top:0in;
margin-right:0in;
margin-bottom:10.0pt;
margin-left:0in;
line-height:115%;
mso-pagination:widow-orphan;
font-size:12.0pt;
mso-bidi-font-size:11.0pt;
font-family:Garamond;
mso-ascii-font-family:Garamond;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Garamond;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Garamond;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
{mso-style-priority:34;
mso-style-unhide:no;
mso-style-qformat:yes;
margin-top:0in;
margin-right:0in;
margin-bottom:10.0pt;
margin-left:.5in;
mso-add-space:auto;
line-height:115%;
mso-pagination:widow-orphan;
font-size:12.0pt;
mso-bidi-font-size:11.0pt;
font-family:Garamond;
mso-ascii-font-family:Garamond;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Garamond;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Garamond;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;}
p.MsoListParagraphCxSpFirst, li.MsoListParagraphCxSpFirst, div.MsoListParagraphCxSpFirst
{mso-style-priority:34;
mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-type:export-only;
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
margin-bottom:.0001pt;
mso-add-space:auto;
line-height:115%;
mso-pagination:widow-orphan;
font-size:12.0pt;
mso-bidi-font-size:11.0pt;
font-family:Garamond;
mso-ascii-font-family:Garamond;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Garamond;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Garamond;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;}
p.MsoListParagraphCxSpMiddle, li.MsoListParagraphCxSpMiddle, div.MsoListParagraphCxSpMiddle
{mso-style-priority:34;
mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-type:export-only;
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
margin-bottom:.0001pt;
mso-add-space:auto;
line-height:115%;
mso-pagination:widow-orphan;
font-size:12.0pt;
mso-bidi-font-size:11.0pt;
font-family:Garamond;
mso-ascii-font-family:Garamond;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Garamond;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Garamond;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;}
p.MsoListParagraphCxSpLast, li.MsoListParagraphCxSpLast, div.MsoListParagraphCxSpLast
{mso-style-priority:34;
mso-style-unhide:no;
mso-style-qformat:yes;
mso-style-type:export-only;
margin-top:0in;
margin-right:0in;
margin-bottom:10.0pt;
margin-left:.5in;
mso-add-space:auto;
line-height:115%;
mso-pagination:widow-orphan;
font-size:12.0pt;
mso-bidi-font-size:11.0pt;
font-family:Garamond;
mso-ascii-font-family:Garamond;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Garamond;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Garamond;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;}
.MsoChpDefault
{mso-style-type:export-only;
mso-default-props:yes;
font-size:11.0pt;
mso-ansi-font-size:11.0pt;
mso-bidi-font-size:11.0pt;
font-family:Garamond;
mso-ascii-font-family:Garamond;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:Garamond;
mso-fareast-theme-font:minor-latin;
mso-hansi-font-family:Garamond;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;}
.MsoPapDefault
{mso-style-type:export-only;
margin-bottom:10.0pt;
line-height:115%;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.25in 1.0in 1.25in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-paper-source:0;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
@list l0
{mso-list-id:887296995;
mso-list-type:hybrid;
mso-list-template-ids:1214556060 67698703 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
@list l0:level1
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level2
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level3
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l0:level4
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level5
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level6
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l0:level7
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level8
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l0:level9
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l1
{mso-list-id:930430052;
mso-list-type:hybrid;
mso-list-template-ids:-296974276 67698703 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l1:level1
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l1:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:"Courier New";
mso-bidi-font-family:"Courier New";}
@list l1:level3
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Wingdings;}
@list l1:level4
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Symbol;}
@list l1:level5
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:"Courier New";
mso-bidi-font-family:"Courier New";}
@list l1:level6
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Wingdings;}
@list l1:level7
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Symbol;}
@list l1:level8
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:"Courier New";
mso-bidi-font-family:"Courier New";}
@list l1:level9
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Wingdings;}
@list l2
{mso-list-id:1858616855;
mso-list-type:hybrid;
mso-list-template-ids:1906109774 67698703 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
@list l2:level1
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level2
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level3
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l2:level4
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level5
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level6
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
@list l2:level7
{mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level8
{mso-level-number-format:alpha-lower;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;}
@list l2:level9
{mso-level-number-format:roman-lower;
mso-level-tab-stop:none;
mso-level-number-position:right;
text-indent:-9.0pt;}
ol
{margin-bottom:0in;}
ul
{margin-bottom:0in;}
-->
</style>
<br />
<div class="MsoNormal">
Be sure to separate symptoms of a problem from the problem
itself.<span style="mso-spacerun: yes;"> </span>This can sometimes be harder
than it seems.<span style="mso-spacerun: yes;"> </span>Sometimes the problem is
a few layers below the surface.<span style="mso-spacerun: yes;"> </span>For
example, assume you get the following issue reports and feature requests:</div>
<div class="MsoListParagraphCxSpFirst" style="mso-list: l1 level1 lfo1; text-indent: -.25in;">
<span style="mso-bidi-font-family: Garamond; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">1.<span style="font: 7.0pt "Times New Roman";">
</span></span></span>Please add a button to all list screens to
export data to Excel.</div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l1 level1 lfo1; text-indent: -.25in;">
<span style="mso-bidi-font-family: Garamond; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">2.<span style="font: 7.0pt "Times New Roman";">
</span></span></span>Whenever running a query that returns a lot of
data (e.g. 10K rows) the list screens take a long time to return.</div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l1 level1 lfo1; text-indent: -.25in;">
<span style="mso-bidi-font-family: Garamond; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">3.<span style="font: 7.0pt "Times New Roman";">
</span></span></span>We’d like to be able to run very basic
(read-only) queries by linking to some tables through MS Access.<span style="mso-spacerun: yes;"> </span>But in order to do that we need an Oracle
client installed on our machine.<span style="mso-spacerun: yes;"> </span>We also
need a username/password for the database.</div>
<div class="MsoListParagraphCxSpLast" style="mso-list: l1 level1 lfo1; text-indent: -.25in;">
<span style="mso-bidi-font-family: Garamond; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">4.<span style="font: 7.0pt "Times New Roman";">
</span></span></span>Please add “week ending” and “month” to the
return fields for all list screens.</div>
<div class="MsoNormal">
On the surface these seem like simple, disparate problems to
be solved.<span style="mso-spacerun: yes;"> </span>So you might come up with
solutions like this:</div>
<div class="MsoListParagraphCxSpFirst" style="mso-list: l0 level1 lfo2; text-indent: -.25in;">
<span style="mso-bidi-font-family: Garamond; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">1.<span style="font: 7.0pt "Times New Roman";">
</span></span></span>“Sure – we can add an export button”.</div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo2; text-indent: -.25in;">
<span style="mso-bidi-font-family: Garamond; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">2.<span style="font: 7.0pt "Times New Roman";">
</span></span></span>“Hmmm – we’ll have to look at the query – maybe
it can be tuned.”</div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo2; text-indent: -.25in;">
<span style="mso-bidi-font-family: Garamond; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">3.<span style="font: 7.0pt "Times New Roman";">
</span></span></span>“A little unorthodox.<span style="mso-spacerun: yes;"> </span>We’ll have to get approval from IT management
that this is ok but this is not technically challenging”.</div>
<div class="MsoListParagraphCxSpLast" style="mso-list: l0 level1 lfo2; text-indent: -.25in;">
<span style="mso-bidi-font-family: Garamond; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">4.<span style="font: 7.0pt "Times New Roman";">
</span></span></span>“Sure – easy enough”</div>
<div class="MsoNormal">
But if we look a little deeper we can see that these are
symptoms of a deeper problem: the users do not have an easy way to perform
management reporting and data analysis.<span style="mso-spacerun: yes;">
</span>Neither this system nor other systems (e.g. a data warehouse) are
addressing these business needs.<span style="mso-spacerun: yes;"> </span>Think
about it.<span style="mso-spacerun: yes;"> </span>Here is a different way of
looking at each of the issues:</div>
<div class="MsoListParagraphCxSpFirst" style="mso-list: l2 level1 lfo3; text-indent: -.25in;">
<span style="mso-bidi-font-family: Garamond; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">1.<span style="font: 7.0pt "Times New Roman";"> </span></span></span>Adding an export button is fairly harmless but
the reason they need it is probably because they are doing analysis in Excel
that the system is not helping them with.</div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l2 level1 lfo3; text-indent: -.25in;">
<span style="mso-bidi-font-family: Garamond; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">2.<span style="font: 7.0pt "Times New Roman";"> </span></span></span>There’s no way they’re reading through 10K
lines of data line-by-line.<span style="mso-spacerun: yes;"> </span>The reason they’re
doing this is probably because they’re analyzing the data in ways that the
system does not support.</div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l2 level1 lfo3; text-indent: -.25in;">
<span style="mso-bidi-font-family: Garamond; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">3.<span style="font: 7.0pt "Times New Roman";"> </span></span></span>There’s no way they’d be desperate enough to
navigate the oddities of our back-end if the system better supported their
analytical needs.</div>
<div class="MsoListParagraphCxSpLast" style="mso-list: l2 level1 lfo3; text-indent: -.25in;">
<span style="mso-bidi-font-family: Garamond; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">4.<span style="font: 7.0pt "Times New Roman";"> </span></span></span>Hmmm.<span style="mso-spacerun: yes;"> </span>I
am guessing they want those fields for time-trend reporting or filtering.<span style="mso-spacerun: yes;"> </span>This suggests that they’re doing their
analysis off of large report results which is another symptom of the fact that
the system does not support their analytical needs.</div>
<div class="MsoNormal">
Whenever possible focus on ideas to treat the problem not
the symptoms.<span style="mso-spacerun: yes;"> </span>Treating symptoms is ok as
a short-term alternative but it is rarely the way to go in the long-term.<span style="mso-spacerun: yes;"> </span>To use a medical analogy cough syrup is
useful and may effectively treat the symptoms of an infection but antibiotics
have the capability to address the root cause. Dig a little deeper and be sure you get to the underlying problem.</div>
Joseph Lynchhttp://www.blogger.com/profile/11886779384421780164noreply@blogger.com1tag:blogger.com,1999:blog-4632619500491960788.post-5773182898185084132014-09-18T10:30:00.000-04:002014-09-18T10:30:37.888-04:00A Response to the Reactive ManifestoThe Reactive Manifesto published by Typesafe is getting a great deal of attention in the Scala community. A <a href="http://typesafe.com/blog/reactive-manifesto-20" target="_blank">new version </a>was posted yesterday and I could not help but reply with criticism that has been bothering me for some time. The Reactive Manifesto appears to be a thinly veiled way to back into Akka being the cure for all ills. I think this is an irresponsible message especially from a company like Typesafe that is guiding a great number of people that are just venturing into Scala. One sure way to hurt the Scala community is to offer the advice that one should adhere to a reference architecture that is best applied for only a certain set of problems. My comment/reply to the Manifesto appears below in its entirety. I hope that, at a minimum, it stimulates some thought for those that were intending to jump into the Akka pool without fully understanding why.<br />
<br />
<div class="post-message " data-role="message" dir="auto">
<i>Jonas:</i><br />
<br />
<i>I am the VP of Engineering at LeadiD a tech startup
based in Ambler, PA. We are building out a large, complex stack for
servicing web transactions at scale. We already process billions of web
service calls each month. We are gung-ho on Scala even though it’s new
to us here. But I must confess that so far I’ve felt the Reactive
Manifesto to be a bit, if you’ll forgive me, contrived. When I read it,
it seems that we’ve all been suffering from ADD (Akka Deficit Disorder)
and we just didn’t know it. But actors (which are at the heart of
Akka) are not the cure for everything. They are a great solution for
certain types of problems.</i><br />
<br />
<i>Allow me to comment on the system attributes in the Manifesto:</i><br />
<br />
<i>Responsive - An essential attribute. This is a function of proper provisioning. There are many ways to achieve this.</i><br />
<br />
<i>Resilient
- An essential attribute. Most mission-critical systems ensure this
using a load balancer and a cluster(s) of servers. Does not require the
use of actors or supervision hierarchies.</i><br />
<br />
<i>Elastic - An essential
attribute. Akka does have a sweet spot here. But can be achieved using
elastic provisioning techniques by rolling your own in a DevOps manner
or by using third party tools.</i><br />
<br />
<i>Message-Driven - This is not an
essential attribute. You’ve fast-forwarded to a solution, here. It’s a
means to an end and it basically describes actors. Increasing asynch
is very important as a piece of the puzzle. But synchronous processing
of a request that does not lend itself to being split up or parallelized
still has its place.</i><br />
<br />
<i>There are some complexities with actors:</i><br />
<ul>
<li><i>Actors are a mechanism to solve a distributed computing problem - that
is, when a given request is best split up across a number of machines.
When a given problem does not lend itself to distributed computing it’s
not a great fit. Many CRUD functions (even at scale) out there are
served best by a cluster of nearly identical, load-balanced app servers
each of which is self-contained.</i></li>
<li><i>Unless you have a distributed
computing problem location transparency is not a good thing. I want the
caller to know he’s making a network call vs. an in memory lookup.</i></li>
<li><i>Given the buzz people will gravitate to actors because it appears to be
the latest / greatest. But unless their problem merits it they’ve
opened up new cans of worms. If the work can be handled in a single
process actors might not be the right choice.</i></li>
</ul>
<i>Rich Hickey says it best:</i><br />
<br />
<i>“I chose not to use the Erlang-style actor model for same-process state management in Clojure for several reasons:</i><br />
<ul>
<li><i>It is a much more complex programming model, requiring 2-message
conversations for the simplest data reads, and forcing the use of
blocking message receives, which introduce the potential for deadlock.
Programming for the failure modes of distribution means utilizing
timeouts etc. It causes a bifurcation of the program protocols, some of
which are represented by functions and others by the values of messages.</i></li>
<li><i>It doesn't let you fully leverage the efficiencies of being in the same
process. It is quite possible to efficiently directly share a large
immutable data structure between threads, but the actor model forces
intervening conversations and, potentially, copying. Reads and writes
get serialized and block each other, etc.</i></li>
<li><i>It reduces your
flexibility in modeling - this is a world in which everyone sits in a
windowless room and communicates only by mail. Programs are decomposed
as piles of blocking switch statements. You can only handle messages you
anticipated receiving. Coordinating activities involving multiple
actors is very difficult. You can't observe anything without its
cooperation/coordination - making ad-hoc reporting or analysis
impossible, instead forcing every actor to participate in each protocol.</i></li>
<li><i>It is often the case that taking something that works well locally and
transparently distributing it doesn't work out - the conversation
granularity is too chatty or the message payloads are too large or the
failure modes change the optimal work partitioning, i.e. transparent
distribution isn't transparent and the code has to change anyway.”</i></li>
</ul>
<i>And then there is Fowler’s First Law of Distributed Object Design: Don’t distribute your objects! (unless you must)</i><br />
<br />
<i>Typesafe
is shepherding a great number of people in the Scala community on how
to best use the language and its platform. By pushing Reactive (which
basically equals Akka) on its front page as the cure for all ills it
suggests that you must be missing something if you’re not doing it this
way. But the way that’s been outlined is most appropriate in a
distributed computing setup. And many distributed computing problems
arising out of large datasets, for example, can be addressed using other
techniques such as MapReduce.</i><br />
<br />
<i>While the Akka platform is very
powerful I believe that the Scala community could use better education
from Typesafe on when it is best used as well as when to consider
alternative architectures. Balance will go a long way toward
credibility. Thanks so much for the work. But please bear in mind that
if Akka is a hammer that does not imply that everything is a nail.</i><br />
<br />
<i>Joe Lynch</i><br />
</div>
<br />
<br />
<br />
<br />
<br />Joseph Lynchhttp://www.blogger.com/profile/11886779384421780164noreply@blogger.com4tag:blogger.com,1999:blog-4632619500491960788.post-80072968373847213012014-04-08T22:23:00.001-04:002014-09-18T19:54:22.511-04:00Build Upon Rock: Understand the Business NeedBecause software developers are in the business of delivering solutions our thinking and discussions with business owners tend to be solution-oriented. It’s not uncommon to hear things like this from business owners:
<br />
<ul>
<li>“I really need a new column added to the F105 report – the total processing time.”
</li>
<li>“I need a new screen that tracks inventory.”
</li>
</ul>
<br />
It’s also not uncommon for developers to listen to business owners talk about their issues and jump to well-known solutions and say things like:
<br />
<ul>
<li>“What you need is a CRM system.”
</li>
<li>“The F109 screen will take of everything you need. I’ll show you how to use it.”
</li>
</ul>
<br />
Thinking about solutions is not a bad thing but it can lead to mistakes if the business problem is not framed properly. You can tell that you’ve framed a business problem properly when its description has nothing to do with a system, per se. Take the case of adding a column to the F105 report. Rather than respond – “ok – we’ll get right on that,” start by getting to the underlying business need:
<br />
<br />
<b>Developer</b>: “What's changed? What is motivating the need to add the total processing time to the report?”
<br />
<br />
<b>Business Owner</b>: “We’ve changed our processes so that we’re reporting on this to our customers. Upper management is also really hot on it – we had some very slow fulfillment times last month.”
<br />
<br />
<b>Developer</b>: “Oh. Ok. It’s easy to add it to the report but that’s just a lagging indicator. Do you think you might need tools that alert you to orders that haven’t been fulfilled in a certain amount of time? Then you’d have a chance to head the issues off before they reach a certain point of criticality. So rather than just a passive indicator we could give you a proactive tool for managing exceptions.”
<br />
<br />
<b>Business Owner</b>: “Yeah. That’s even better.”
<br />
<br />
If you understand the underlying business need you will be able to offer alternative solutions and improve upon solutions that may have already been suggested. You’ll be that much more valuable and seen as an architect of solutions, not just someone who implements things blindly without understanding implications. Moreover, understanding the underlying business needs will teach you more and more about the business that you are supporting which will make you far more effective in your work. You’ll be able to make logical deductions based on business understanding that would otherwise not be obvious. And you’ll become the go-to person when your business owners are facing a tough problem – business owners love people that can speak their language and that can help bridge the gap between what they think they need and what they really need.
<br />
<br />
Related to understanding business needs, it is imperative to ensure that one has framed a problem properly before beginning to work on it. An inaccurate framing of a problem can lead to serious mistakes not the least of which is that one may be focusing on solving the <i>wrong</i> problem. As human beings, our brains are conditioned through millions of years of evolution to see patterns in order for us to process information quickly – we are wired to put things into categories and react accordingly as this has been necessary for the survival of the species. For example, if one perceives a threat (e.g. a hissing cobra) the amygdala takes over and ensures that we react immediately via a fight or flight response. The amygdala is an ancient part of the brain which is not used to solve a difficult math problem – a different portion of the brain (the frontal lobe) is used to solve that problem. Our biology itself is pre-conditioned for pattern-recognition.
<br />
<br />
As seers of patterns, it is easy to leap to conclusions in either the definition of the problem or worse, its solution. We sometimes make things fit within a box. Sometimes we may even reverse-engineer a problem to fit a pre-conceived solution! Think about it. “I’ve got a meeting with the head of the Customer Service team. Sounds like he needs a CRM.” Then you go to the meeting and due to the human tendency toward <a href="http://en.wikipedia.org/wiki/Confirmation_bias" target="_blank">confirmation bias</a> all you hear are the issues that a CRM could help solve. “See – told you he needed a CRM.” But you walk away not hearing the fact that this person is dealing with other issues that you might have been able to help with. And after all, have we even framed the problem? What is the problem? CRM-Deficit-Disorder?
<br />
<br />
Imagine the following scenario. A business owner comes running into your office. “I can’t run the F105 report! I enter the search criteria and then the application just crashes. I need to get these numbers to our customer within an hour. Help!” Being a diligent production support team member you make sure you can replicate the issue. Good – you can. You start seeing if you can fix the crash. You queue up the testing and deployment staff – “hey – we’ve got a hot bug fix coming – be ready”. 45 minutes goes by and you’re still having trouble figuring out why it’s crashing. The business comes in very concerned. “Well?” “I’m working on it” you say. 15 minutes go by and then 30 minutes and then a few hours. By the time you get the issue fixed it’s 7:00 PM. Your business owner says – “Since we didn’t get it out by 4 PM the customer’s going to be pretty angry. But thanks for getting it done as quickly as you could. I know you tried.” You say to yourself – “I did the best I could but I only had a few hours' notice. Oh well.” You go home feeling pretty good about yourself. You kiss the kids goodnight and hold your head up high.
<br />
<br />
<i>But did you do a good job?</i> What was the problem? You might think – “Duh! Clearly the problem was that there was a bug in the F105 report that was preventing it from being run”. Wrong! The immediate problem was that the business owner was not able to submit required information to the customer by 4:00 thus causing the company to fail in the customer’s eyes. Framed that way, one obvious solution would have been to run the query behind the report (manually) and give the business owner the results. But business owners are not always aware of options available to them – we have to help flesh them out – most have no idea how a system is put together. Framing a problem properly can lead to a broader solution space and can lead one to the best solution faster. Framing a problem incorrectly can, in some cases, lead to disaster.<br />
<br />
Understand the business need, frame the problem properly and your solutions will be built upon rock.Joseph Lynchhttp://www.blogger.com/profile/11886779384421780164noreply@blogger.com4