{"id":843,"date":"2011-10-17T08:09:15","date_gmt":"2011-10-17T14:09:15","guid":{"rendered":"http:\/\/www.jeffwofford.com\/?p=843"},"modified":"2023-11-14T20:42:59","modified_gmt":"2023-11-15T02:42:59","slug":"keep-taking-steps-forward","status":"publish","type":"post","link":"https:\/\/www.jeffwofford.com\/wp\/?p=843","title":{"rendered":"Keep Taking Steps Forward"},"content":{"rendered":"<div class=\"wp-block-image\">\n<figure class=\"alignright\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"223\" src=\"https:\/\/i0.wp.com\/www.jeffwofford.com\/wp\/wp-content\/uploads\/2011\/10\/stuck-hedge-hog.jpg?resize=300%2C223&#038;ssl=1\" alt=\"\" class=\"wp-image-878\" title=\"Stuck Hedgehog\" srcset=\"https:\/\/i0.wp.com\/www.jeffwofford.com\/wp\/wp-content\/uploads\/2011\/10\/stuck-hedge-hog.jpg?resize=300%2C223&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.jeffwofford.com\/wp\/wp-content\/uploads\/2011\/10\/stuck-hedge-hog.jpg?w=700&amp;ssl=1 700w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"has-drop-cap wp-block-paragraph\">In the last couple of posts I&#8217;ve talked about a programmer&#8217;s greatest enemy: <a title=\"A Programmer's Greatest Enemy\" href=\"https:\/\/www.jeffwofford.com\/?p=835\">getting stuck<\/a>. I talked about the various <a title=\"Four Kinds of Stuck\" href=\"https:\/\/www.jeffwofford.com\/?p=838\">levels<\/a> of how stuck you can get, from getting stuck while trudging through documentation to getting stuck because you don&#8217;t have the resources\u2014passwords, files\u2014that you need to perform a task.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This leads me to my ultimate advice for how to avoid getting stuck and how to get unstuck.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The secret to getting and staying unstuck is to&nbsp;<em><strong>keeping taking steps forward<\/strong>.<\/em> Simple as that sounds, it is more difficult than it seems, and many programmers never master it.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p class=\"wp-block-paragraph\">In order to&nbsp;keep taking steps forward you first have to&nbsp;<strong>know what forward is<\/strong>. What are you trying to accomplish? What&#8217;s the&nbsp;<em>real<\/em> task? Tragically, programmers often get stuck on tasks that aren&#8217;t really even what they&#8217;re supposed to be doing\u2014aren&#8217;t even really all that valuable. When you&#8217;re chasing down a bug in a tool that&#8217;s meant to help you find an optimization for a class that you&#8217;re trying to fix in order to solve a user experience complaint, it&#8217;s easy to forget that the&nbsp;<em>user experience complaint<\/em> is your true task, not the bug in the tool.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">From what I&#8217;ve observed, programmers, in general, tend to obsess. We like to dive down into the nitty-gritty of things. And we tend to get distracted, entranced by the pretty pixels on screen, the annoying obstacles, the intriguing puzzles that programming throws our way. Pretty soon, we&#8217;re pulling our hair out over a problem that doesn&#8217;t even matter.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This seems to happen to me whenever I use <em>awk<\/em>. Awk is a small programming language that lets you manipulate text easily within Unix. I often use it to manipulate groups of files. Say, for example, I&#8217;ve got a folder full of images. I want to rename all of the images so that each name has an ascending number at the end. Awk is great at this kind of thing. You can write a simple, two-line awk program to read the file names, keep a tally, append the tally number to the filename, and then direct the renaming.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But I don&#8217;t know <em>awk<\/em> that well. So whenever I want to write an <em>awk<\/em> program, I have to go back to the documentation, study up again a little bit, and then experiment with solutions. Pretty soon I&#8217;m debugging some archaic little piece of <em>awk<\/em> code that won&#8217;t quite do what I want. Two hours later I remember, &#8220;Oh yeah, I was really just wanting to rename these files. I suppose I could just rename them by hand&#8230;.&#8221;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To avoid getting stuck, you&#8217;ve got to remember which way is <em>forward<\/em>.&nbsp;So before launching off on a long Google search or a marathon debugging session, ask yourself, &#8220;What am I&nbsp;<em>really<\/em> working on today? Is this long, arduous sub-sub-task really essential to what I need to accomplish?&#8221; Often, it&#8217;s not. And when it&#8217;s not, pull up. Get clear, Wedge. You can&#8217;t do any more good back there. Go back to focusing on what is truly crucial.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once you know what forward is, then you can take <strong>steps forward<\/strong>. A step forward is an action that&nbsp;<em>actually moves toward resolving the problem<\/em>. It&#8217;s not just a step. It&#8217;s a step&nbsp;<strong><em>forward<\/em><\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One example of this is in debugging. I see lots of programmers go round and around for hours chasing down a single bug. They tell themselves that they&#8217;re spending hours because the bug is really difficult. But then a stronger programmer comes along and fixes the bug in minutes. Ouch.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">What&#8217;s the difference between the junior programmer who spends hours and the master who spends minutes? The difference is that a master debugger knows how to make a strong, positive step every time he or she runs the program.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Many programmers debug by guessing, dabbling with the code, then running the application to see what their dabbling did. Two hundred iterations of dabbling later, they&#8217;re still searching for the problem.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The master programer doesn&#8217;t dabble. Each step is a clear, targeted, incisive experiment to test a particular hypothesis about what is causing the bug.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The junior programmer performs an O(<em>n<\/em>) algorithm. Make a random guess. Test it. Make another random guess. Test it. Follow your intuition. Use your instincts. Go with the flow.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This particular kind of flow leads straight to <em>stuck.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The master programmer performs an O(log<em>n<\/em>) algorithm <em>at worst.<\/em> At worst, each experiment invalidates half of the possible causes. Some experiments, thoughtfully chosen, eliminate a much larger swath. Therefore even if there are millions of possible causes for the bug\u2014millions of lines of code\u2014the tests must ultimately converge somewhere. And they will do so in a relatively small number of steps.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Always take steps&nbsp;<em>forward<\/em>, not just&nbsp;<em>around<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, take clear, distinct&nbsp;<strong><em>steps<\/em><\/strong>. Programmers often work on intuition, and that&#8217;s great. Intuitions about what classes to write, what functions to implement, whether a variable should be an&nbsp;<em>int <\/em>or an&nbsp;<em>unsigned int<\/em> or a&nbsp;<em>char<\/em>. Intuitions are fine, and not every intuition has to be rigorously examined.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But when you&#8217;re faced with a big problem that can cost you <em>hours out of your life<\/em>, you need more than intuition. You need clear, distinct progress. You need discrete steps that enable you to see whether you&#8217;re moving forward, backward, or not at all.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When I&#8217;m debugging a big bug, for example, I tend to write down each step in the debugging process. Here, for example, are some notes from a bug I fixed earlier this year. They won&#8217;t mean a whole lot to you\u2014it was a crash caused by a bug in a smart pointer class I had written\u2014but it will give you a sense for the kinds of notes I take. Each line represents a finding that I documented after performing a round of hypothesizing and testing.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Occurs in Object::Release(). Assertion failure. The problem is that m_nReferences is 0 when the function is called.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The function is called in this case by ObjectSingleton&lt; AssetManager&gt;::~ObjectSingleton(), which nullifies the s_pInstance smart pointer, which calls Release().<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The destructor is called, ironically, by Object::Release(), again where this == the asset manager.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So in other words, the asset manager&#8217;s release function is called, bringing the ref count to 0, which causes the object to be deleted, which causes the self-pointer to be set to 0, which causes Release() to be called again.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I&#8217;m not sure yet whether this data describes the whole problem or if there is more to look at (e.g. why is the first Object::Release() called?). But let&#8217;s look at what we have so far&#8230;.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">About 2-3 minutes passed between each of those lines. Those minutes were filled with setting up a test, then quickly compiling and running the code to confirm the results of the test. By writing down my findings after each step, I was made more conscious of the actions I was taking and how to keep moving forward. I had a handy log of where I had been so that I wasn&#8217;t tempted to backtrack. And by turning my thoughts into sentences I made sure I knew what I was doing and why.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Intuition is great, but it tends to drift around. Drifting isn&#8217;t good for making progress. To avoid getting stuck, I corral my intuition with notes. And it really helps. Even the severe bugs that used to take me days now take at most hours. And it&#8217;s a rare bug that&#8217;s that severe. When I take discrete steps forward, few bugs take more than a few minutes to find and fix.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I&#8217;ve been talking about debugging as an example of taking clear, forward steps. But I find that these ideas apply in any kind of programming task. Whether it&#8217;s designing a class, working out a new algorithm, publishing an app to the App Store, or even reading through API documentation, knowing what <em>forward<\/em> is, and then taking clear steps that forcefully move you <em>forward<\/em> is the greatest antidote to getting stuck.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to minimize the stuckness in your life as a programmer, make sure you know what &#8220;forward&#8221; is, then keep taking steps in that direction.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the last couple of posts I&#8217;ve talked about a programmer&#8217;s greatest enemy: getting stuck. I talked about the various levels of how stuck you can get, from getting stuck while trudging through documentation to getting stuck because you don&#8217;t have the resources\u2014passwords, files\u2014that you need to perform a task. This leads me to my &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.jeffwofford.com\/wp\/?p=843\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Keep Taking Steps Forward&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[18,15,17],"tags":[],"class_list":["post-843","post","type-post","status-publish","format-standard","hentry","category-productivity","category-programming","category-thinking"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.jeffwofford.com\/wp\/index.php?rest_route=\/wp\/v2\/posts\/843","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jeffwofford.com\/wp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jeffwofford.com\/wp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jeffwofford.com\/wp\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jeffwofford.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=843"}],"version-history":[{"count":9,"href":"https:\/\/www.jeffwofford.com\/wp\/index.php?rest_route=\/wp\/v2\/posts\/843\/revisions"}],"predecessor-version":[{"id":2151,"href":"https:\/\/www.jeffwofford.com\/wp\/index.php?rest_route=\/wp\/v2\/posts\/843\/revisions\/2151"}],"wp:attachment":[{"href":"https:\/\/www.jeffwofford.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=843"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jeffwofford.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=843"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jeffwofford.com\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=843"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}