<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>Latest entries from timstall.dotnetdevelopersjournal.com</title><link>http://timstall.dotnetdevelopersjournal.com/</link><description></description><copyright>Copyright 2010 timstall.dotnetdevelopersjournal.com</copyright><generator></generator><lastBuildDate>Fri, 19 Mar 2010 05:01:00 GMT</lastBuildDate><image><title>Latest entries from timstall.dotnetdevelopersjournal.com</title><url>http://res.sys-con.com/portlet/163/featured-blog-graphic-145.gif</url><link>http://timstall.dotnetdevelopersjournal.com/</link></image><ttl>360</ttl><docs>http://backend.userland.com/rss</docs><item><title>BOOK: Managing Humans</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/book_managing_humans.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/book_managing_humans.htm</link><pubDate>Fri, 19 Mar 2010 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=book%5Fmanaging%5Fhumans</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[About two Christmases ago, I was shopping for a gift for a tech buddy. Browsing through the local Barnes &amp; Noble, I saw this yellow book &quot;<a href="http://www.amazon.com/Managing-Humans-Humorous-Software-Engineering/dp/159059844X/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1268968096&amp;sr=1-1">Managing Humans</a>&quot;. I thought to myself &quot;what technical geek doesn&#39;t need to know better people and management skills?&quot; Relieved to have found the perfect gift, I never thought much about that book since. Then a coworker suggested Michael Lopp&#39;s <a href="http://www.randsinrepose.com/">Rands in Repose</a> blog. I was impressed with Michael&#39;s take on how &quot;software engineers&quot; meet &quot;people skills&quot;, saw that it was the same guy who wrote &quot;Managing Humans&quot;, and figured that two (indirect) endorsements for the same book, combined with my quest to improve my people skills, meant I should buy it. $16.49 and 8 days later, I had the book in my hands, and could barely put it down. With each chapter, I thought to myself &quot;this guy <em>really </em>gets it&quot;. <p>The book is divided into 34 small chapters, each based on insightful stories based on in-the-trenches experiences. Lots of people-books offer fluff: &quot;be nice to all your coworkers&quot;, &quot;work hard&quot;, &quot;always brush your teeth so your bad breath doesn&#39;t alienate your coworkers&quot;, etc... Michael bypasses the obvious and gets to the good stuff. Some of the big points I took away:</p><p>Blunt Truths</p><ol><li>&quot;Your manager is not a manager until they&#39;ve participated in a layoff.&quot; (pg. 15)</li><li>&quot;If you&#39;re sitting in a meeting where you&#39;re unable to identify any players, get the hell out.&quot; (pg. 23)</li><li>&quot;Remember that for every person on the team who has a strong opinion regarding the decision, there are probably four other coworkers who just want someone to make a decision so that they can get back to work.&quot; (pg. 28)</li><li>&quot;you aren&#39;t a company until 1.0 is done.&quot; (pg. 77)</li><li>About reacting vs. thinking, and being too busy: &quot;when you&#39;re busy, you&#39;re not thinking, you&#39;re reacting.&quot; (pg. 83)</li><li>About &quot;Malcolm Events&quot; - &quot;Seemingly insignificant events that are intent on screwing you in an unlikely way.&quot; (pg. 93) &quot;The only way you&#39;re going to learn to identify potential Malcolm events is by going through some horrible, horrible experiences.&quot; (pg. 96) Part of avoiding these events is clear and tough communication that most people want to shy away from, such as team status reports that say &quot;We&#39;re not doing Phil&#39;s favorite feature.&quot;</li><li>&quot;nothing gets everyone&#39;s attention like a deadline.&quot; (pg. 107)</li><li>About finding the anchor in a meeting - &quot;Just wait for someone to say something controversial and see who everyone looks at.&quot; (pg. 148)</li><li>&quot;Like it or not, your boss has as much effect on your career as you do&quot; (pg. 163)</li><li>&quot;A reorg isn&#39;t over until someone important has printed out a new organizational chart and presented it in front of the entire company.&quot; (pg. 174)</li><li>About outsourcing your job - &quot;You could be outsourced because your job is so richly defined that it can be documented and explained to any reasonable professional on the planet...&quot; (pg. 179) &quot;Jobs that can be &#39;well specified&#39; are being shipped offshore.&quot; (pg. 183)</li><li>&quot;A micromanager does not trust.&quot; (pg. 189)</li><li>&quot;Guy who knows the people are the business.&quot; (pg. 190)</li></ol><p>Other misc quotes</p><ol><li>&quot;you are not talking to a person when you talk with your manager; you are talking to the organization.&quot; (pg. 11)</li><li>&quot;understanding your manager&#39;s place in the political food chain is the trickiest because you&#39;re often not in the meetings where he is interacting with his superiors.&quot; (pg. 14)</li><li>&quot;In any freakout, there is normally a very noisy preamble which is designed to get your attention.&quot; (pg. 18)</li><li>&quot;your job is not just management of people, it&#39;s management of information.&quot; (pg. 105)</li></ol>]]></description><category>books</category><category>management</category></item><item><title>10 tips to write shorter emails</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/10_tips_to_write_shorter_emails.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/10_tips_to_write_shorter_emails.htm</link><pubDate>Wed, 10 Mar 2010 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=10%5Ftips%5Fto%5Fwrite%5Fshorter%5Femails</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[There are some who think that the volume of email you send out directly reflects how much work you&#39;ve done. So if you cc twice as many people, you&#39;ve done twice as much work. For the rest of us, reading long emails is a time-consuming nuisance. To avoid being that person who irritates everyone with a daily novel-worth of emails, here&#39;s some tips to write shorter emails: <ol><li>The shortest email is the one you never even had to write- perhaps the issue can be resolved with a quick IM or water-cooler conversation.</li><li>Refer to external resources with the URL instead of pasting large chunks into your email (like &quot;see the wiki page at...&quot;. Although sometimes it may be more convenient for the recipients to just see the content of the URL that you&#39;re referring to (such as if they don&#39;t have access to the target URL).</li><li>Make good use of &quot;To&quot; vs. &quot;CC&quot;. Some people even filter their emails to redirect CC.</li><li>If replying to a long email thread, consider deleting the older history that no longer matters.</li><li>If your email is longer, consider splitting it into a clearly-marked &quot;Summary&quot; (2 lines), and &quot;Details&quot;. Make it easy for a busy person to get the main point of the email in less than 30 seconds.</li><li>&quot;A picture is worth a thousand words&quot;, therefore a picture (like a diagram or graph) can often convey a concept much quicker than verbose text paragraphs. Consider also using outlines and tables for the same reason.</li><li>Differentiate between informal and formal emails. Informal emails are usually quick questions or responses to friendly co-workers about a current issue for which there isn&#39;t a big consequence (example: &quot;Should the confirmation page have a link back to the home page?&quot;). You can make them shorter because you don&#39;t need to re-explain the whole problem or define every term. Formal emails usually have big consequences, are usually followed up with a live meeting or phone call to confirm, and have the details in an attachment. (Example: &quot;Is a rate of $120 per contractor hour acceptable?&quot;) This usually requires them to be longer such that you catch all the influential and controversial ideas to ensure that everyone is on the same page.</li><li>Consider tailoring your email to your target reader and their history of the topic at hand. For example, phrases like &quot;Per our discussion yesterday...&quot; can save you from re-describing a problem. Don&#39;t assume that because email can be forwarded to everyone, you need to write it to the &quot;lowest common denominator&quot;.</li><li>Consider batching multiple questions into one email. Yes, that individual email may be longer, but as a group, the emails will be shorter. It also saves you from having to re-explain the context in each email.</li><li>Use good writing skills to condense your writing.</li></ol>]]></description><category>people</category></item><item><title>Process as Infrastructure Enhancements</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/process_as_infrastructure_enhancements.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/process_as_infrastructure_enhancements.htm</link><pubDate>Mon, 08 Mar 2010 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=process%5Fas%5Finfrastructure%5Fenhancements</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>Most devs I meet <em>hate</em> process, almost like it&#39;s a stupidity-tax from some ivory-tower folk (who themselves don&#39;t actually need to use the process that they&#39;re imposing on others). These devs just want to get the app done, and they think that the process gets in their way with tedious constraints that add no value. I recall projects with &quot;process&quot; like forcing devs to go and update all the internal variable names to be compliant with some new coding standard, or not allowing devs to have admin rights to their own machines until three levels of paperwork is approved (good luck being a dev using a Windows OS if you&#39;re not an admin), or requiring that developers test the app by taking success screen shots of every single step - and then printing out that 600 page doc and getting it signed by QA.</p><p>That sort of stuff bothers me too, but I&#39;m still a big fan of <a href="/tags/?/process"><em>good</em> process</a>. What I realize is that I essentially view &quot;process&quot; as &quot;developer infrastructure enhancements&quot;. I think of process as <a href="/12_more_things_that_will_really_help_your_team.htm">helpful things</a> like automation, unit tests, code generation, proper tools, CI builds, checkout and install scripts, etc...&nbsp; Devs just want to get the job done, and <a href="/what_makes_a_process_good.htm">good process <em>assists</em> them</a> in doing that, it doesn&#39;t burden them with ivory-tower taxes. If your process code-generates the data access layer, then the dev need not do all that manual ADO.Net plumbing code, and hence the dev gets the job done faster.</p><p>Sure, it&#39;s semantics - &quot;process&quot; vs. &quot;infrastructure enhancements&quot;, but semantics are important because it affects how a thought is communicated to other people, and people are important.</p>]]></description><category>process</category></item><item><title>Visual Studio 2008 hanging</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/visual_studio_2008_hanging.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/visual_studio_2008_hanging.htm</link><pubDate>Wed, 03 Mar 2010 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=visual%5Fstudio%5F2008%5Fhanging</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>There&#39;s a lot of <a href="http://www.google.com/#hl=en&amp;source=hp&amp;q=visual+studio+hangs&amp;aq=0&amp;aqi=g10&amp;aql=&amp;oq=visual+studio+han&amp;fp=a048890d3c90c6fc">reasons that Visual Studio hangs</a>. It was hanging for me the other day when I tried to open, and I had a clean checkout. One solution that solved my current problem (thanks to a co-worker):</p><ul><li>Close VS, delete the *.suo file, and try to re-open. I&#39;m sure there&#39;s a reason why,</li></ul><p>2 seconds later, VS was up and running. </p>]]></description><category>coding</category></item><item><title>Advice to a college graduate seeking an IT job</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/advice_to_a_college_graduate_seeking_an_it_job.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/advice_to_a_college_graduate_seeking_an_it_job.htm</link><pubDate>Wed, 24 Feb 2010 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=advice%5Fto%5Fa%5Fcollege%5Fgraduate%5Fseeking%5Fan%5Fit%5Fjob</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>A lot of eager students will be graduating with CS degrees soon. Realistically, with almost 10% unemployment, out-sourcing, and a rough economy, it can be hard for a college-grad to find a tech job.</p><p>Here&#39;s a brain-dump:</p><ol><li><strong>Condition your mind</strong> <ol><li>Until you are employed, your job is to find a job. Prepare to spend at least 4 (maybe 8!) hours a day actively pursuing job opportunities.</li><li>Furthermore, you&#39;re not seeking to &quot;get a job&quot;, you&#39;re looking to &quot;add value&quot; to a company by solving problems in a technical field that you&#39;re passionate about.</li></ol></li><li><strong>Prepare</strong> <ol><li>Set up a <a href="http://www.linkedin.com/">linked-in account</a>. This is an effective and professional way to keep track of people you meet. </li><li>Make the equivalent of a business card that you can hand out as you meet people. Even a card saying something like &quot;Joey Finklestein, my-email, &#39;Technology Specialist&#39;&quot; is good. The goal is to have your contact info easily available.</li><li>Get your resume ready. make sure it downgrades to plain text in case you need to dump it into some online text area. I personally don&#39;t think resumes are the biggest deal. Yes, everything counts. But if you&#39;re blindly submitting your resume online, you&#39;re one among thousands, and it probably won&#39;t matter (sorry). If you meet someone in person, the impression you make will probably dwarf any wordsmith-ing on your resume. If you&#39;ve actually got even a phone screen, the resume has already been sufficient.</li></ol></li><li><strong>Network. Meet people. </strong><ol><li>Especially if you live in a larger city (like Chicago), prepare to go to a user group meeting at least once a week. For example, Chicago has dozens of user groups (<a href="http://www.lcnug.org/">LCNUG</a>, ALT.Net, CNUG, SQL groups, IT, SharePoint, TFS, Design, etc...) Just google it, there&#39;s probably a group. Even if the group isn&#39;t exactly on target, go to the closet-related thing. Try to meet at least 3 people. Talk to them, ask them what they do, get their business card, give them your business card. Often user groups have recruiters who are trying to fill positions - talk to these people. Even if their position isn&#39;t an exact match, they may know of another position, they may have a position that frees up later, or they may just offer you good advice. Plant seeds.</li><li>Keep in touch with your graduating class. Maybe they have leads.</li><li>Go to job fairs - most community colleges offer these on a regular basis.</li></ol></li><li><strong>Start a corporate and professional online presence.</strong> <ol><li>Contribute to online discussion boards (like <a href="http://stackoverflow.com/">http://stackoverflow.com/</a>)</li><li>Contribute to an open-source project (check out <a href="http://www.codeplex.com/">CodePlex.com</a>)</li><li>Consider writing some articles (either start your own blog, or contribute on a free site like <a href="http://www.codeproject.com/">CodeProject</a>. Even if you&#39;re just writing simple articles like &quot;Joey&#39;s C# 101 tutorials&quot;, it&#39;s still beneficial. It tells employers that (1) you&#39;re motivated, (2) you can write (non-tech skills are a great asset), (3) you&#39;re pro-active enough to write. It will also make you more confident after you&#39;ve explained things in an article. Try to write at least two short blogs, or one longer article, <em>every</em> week. Even if you&#39;re &quot;not the writing type&quot;, employers want people who can write, and having a repository of your articles <em>shows</em> them, as opposed to summary statements at the top of a resume that say &quot;has good communication skills&quot;. You can then also list your blog on your resume.</li></ol></li><li><strong>Continual Education </strong>- industry is a different beast than academia. The CS degree is great, but that&#39;s the beginning, not the end. <ol><li>Prepare to spend at least an 1 hour a day reading blogs that are relevant to the job you seek. Find who the top bloggers are in your field of interest, and read them. Probably get an <a href="http://rssbandit.org/download/rss-bandit-download/">RssReader</a>.</li><li>Read the job postings on online sites like <a href="http://www.monster.com/">Monster</a>, <a href="http://www.dice.com/">Dice</a>, <a href="http://hotjobs.yahoo.com/">HotJobs</a>, etc.... You want to make sure you know all the buzzwords, and see what employers are asking for.</li><li>Do charity projects. Many charity groups could really use the free help. Offer to do a tech-related project (assist with their website, do a data migration, write a tool to help them do some task). It doesn&#39;t pay cash, but it does pay in experience and relationships.</li></ol></li><li><strong>About applying...</strong> <ol><li>Ideally you want to meet someone in person (like at a user group). Next best thing is to meet someone in the company who can provide a referral.</li><li>If you do apply online (with no personal reference), don&#39;t put all your eggs in one basket - apply to several companies. But don&#39;t spam Monster. Perhaps submit to a few companies each day, but not more than 10 companies at once. If you don&#39;t hear back from a company within 5 days, move on. Many companies send out an automated &quot;we received your resume note&quot;, and then only personally follow-up if they&#39;re interested. </li></ol></li></ol>]]></description><category>jobs</category><category>people</category></item><item><title>Where 100% Code Coverage is not sufficient</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/where_100_code_coverage_is_not_sufficient.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/where_100_code_coverage_is_not_sufficient.htm</link><pubDate>Wed, 17 Feb 2010 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=where%5F100%5Fcode%5Fcoverage%5Fis%5Fnot%5Fsufficient</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>Sometimes I wish development were as easy as telling junior guys to &quot;follow <a href="/how_to_encourage_standardization.htm">this one metric</a>&quot;, and then they write perfect code. However, it&#39;s not. One example is <a href="/how_many_unit_tests_are_sufficient.htm">how to know when you&#39;ve written enough unit tests</a>. Code Coverage is the obvious metric, and therefore &quot;100% Code Coverage&quot; sounds great. But there are plenty of cases where even 100% coverage doesn&#39;t do the job.</p><p><strong>Case 1: Regular expressions</strong></p><p>Take an email validator, something like so:</p><blockquote><p><span><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">bool</span> IsEmail(<span class="kwrd">string</span> s)<br />{<br />&nbsp;&nbsp;&nbsp; <span class="kwrd">return</span> System.Text.RegularExpressions.Regex.IsMatch(s,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="str">@&quot;\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b&quot;</span>);<br />}</span></p></blockquote><p>A single test would give 100% coverage, but obviously there&#39;s a lot of other paths to check. Ironically, because regular expressions are often used to validate input data, and it&#39;s an in-memory operation (no databases or external files to hit), it&#39;s a prime candidate for <em>lots</em> of unit tests to catch all the boundary conditions - as opposed to just the 1 test needed to reach 100% coverage.</p><p><strong>Case 2: Single-line expressions</strong></p><p>Similar to the previous case, merely calling this method with one set of inputs (say the &quot;less-than&quot; path, such as i1=5 and i2=10), will get 100% coverage. But that wouldn&#39;t test the &quot;greater-than&quot; and &quot;equal to&quot; conditions.</p><blockquote><p><span><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">bool</span> IsGreater(<span class="kwrd">int</span> i1, <span class="kwrd">int</span> i2)<br />{<br />&nbsp;&nbsp;&nbsp; <span class="kwrd">return</span> (i1 &gt; i2);<br />}</span></p></blockquote><p><strong>Case 3: Missing Asserts (bad logic)</strong></p><p>Even with 100% coverage, it doesn&#39;t guarantee that the method logic is correct.</p><p>For example, say you&#39;ve got a CSV-parsing method:</p><blockquote><p><span><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">string</span>[] ParseCsvString(<span class="kwrd">string</span> strLine)<br />{<br />&nbsp;&nbsp;&nbsp; <span class="kwrd">string</span>[] astr = strLine.Split(<span class="str">&#39;,&#39;</span>);<br />&nbsp;&nbsp;&nbsp; <span class="kwrd">return</span> astr;<br />}<br />&nbsp;</span></p></blockquote><p>That is tested by:</p><blockquote><p><span>[TestMethod]<br /><span class="kwrd">public</span> <span class="kwrd">void</span> ParseCsvString()<br />{<br />&nbsp;&nbsp;&nbsp; <span class="kwrd">string</span>[] astr = Foo.ParseCsvString(<span class="str">&quot;a, b, c&quot;</span>);<br />}</span></p></blockquote><p>This will give 100% coverage. However, there are no asserts, so it&#39;s really just showing that the method didn&#39;t throw an exception. Even if a developer adds an assert, they need to make sure it&#39;s asserting the right thing. Say, adding an assert that the returned array is not null, or has a length of 3, misses the logic that trims the white space after each comma. For example, we want elements like &quot;b&quot; (no whitespace), not &quot; b&quot;. In other words, we&#39;d want the ParseCsvString method to loop through each item and Trim() it.</p><p><strong>Case 4: Mocking giving a false sense of security</strong></p><p>Mocking Frameworks, like TypeMock, are very powerful tools for increasing unit test coverage. These tools allow you to &quot;mock out&quot; a method call within code, such as that database or logging call that would be hard to run in a test method.</p><p>While this is great for testing legacy code, it can easily be abused. If every line is mocked out, there&#39;s nothing real that&#39;s left to test. So while it does get high coverage, if used incorrectly, it becomes meaningless.</p><p>&nbsp;</p>]]></description><category>testing</category></item><item><title>BOOK: Winning with People</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/book_winning_with_people.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/book_winning_with_people.htm</link><pubDate>Mon, 01 Feb 2010 18:48:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=book%5Fwinning%5Fwith%5Fpeople</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[I am not a people person. However, I do love software engineering, and I recognize that no software engineering project will succeed without people. 95% of every project failure I&#39;ve ever seen (or heard of) has ultimately been due to people reasons, not technical reasons - two coworkers can&#39;t get along, the manager leads the team in the wrong direction, the tech folks can&#39;t get the requirements from the business folks, the QA and dev teams bicker about what&#39;s &quot;really an issue&quot;, etc... Hence, the cruel irony that just like I work on technical skills, I must also actively work on people skills. Sometimes that means not talking about work during the occasional co-worker lunch. Other times it means reading people-oriented books. This latter activity makes me consciously focus on people interactions. <p>One such book I read was John Maxwells&#39; <a href="http://www.amazon.com/Winning-People-Workbook-John-Maxwell/dp/0785260900/ref=sr_1_2?ie=UTF8&amp;s=books&amp;qid=1264987947&amp;sr=1-2">Winning with People</a>. It was a Christmas present. John has written dozens of books about people, leadership, relationships, and all that. He&#39;s got a lot of wisdom. The book is a series of short chapters on various principles like &quot;Never let the situation mean more than the relationship&quot;, and &quot;the journey with others is slower than the journey alone.&quot; I found it practical, avoiding the common sense clich&eacute;s like &quot;be nice, work hard, etc...&quot;</p><p>I saw a few big take-aways:</p><ul><li>&quot;The journey with others is slower than the journey alone&quot; (pg. 198)</li><li>Quoting Andrew Carnegie, &quot;No man becomes rich unless he enriches others.&quot; (pg. 230)</li><li>&quot;If individuals don&#39;t possess people skills, they very quickly hit a ceiling in their effectiveness.&quot; (pg. 242)</li><li>&quot;Most of us admire and respect people who sustain solid, long-term relationships.&quot; (pg. 259)</li></ul><p>The book is also filled with good quotes, like:</p><ul><li>Quoted T.S. Eliot as saying &quot;Half the harm that is done in this world is due to people who want to feel important.&quot; (pg. 11)</li><li>Quoted someone &quot;the difference between who you are today and who you will be in fie years will be the people you spend time with and the books that you read.&quot; (pg. 13)</li><li>&quot;Actions are remembered long after words are forgotten&quot; (pg. 42)</li><li>&quot;People who add value to others almost always do so intentionally.&quot;</li><li>&quot;We often expect maturity to come with age, but the truth is, sometimes age comes alone.&quot; (pg. 63) - There are <a href="/hiring_based_off_years_of_experience_an_analogy_with_art_an.htm">young devs who are great</a>, and &quot;experienced&quot; devs who are not.</li><li>&quot;Ultimately the things that bring fulfillment involve others.&quot; -&nbsp; I would find it more fulfilling to use an old technology with friends, where we actually ship the product, then a new &quot;cool&quot; technology by myself.</li><li>&quot;The best way to keep from stepping on other people&#39;s toes is to put yourself in their shows.&quot; (pg. 73) [I see this continually in the classic software rivalries: managers who want to deliver vs. techies who want to do &quot;cool&quot; stuff; application developers vs. QA, application developers vs. IT infrastructure, etc...]</li><li>&quot;I made a mistake of trying to impress everybody&quot; (pg. 95) - <a href="/net_is_like_the_galaxy_theyre_both_big_and_getting_bigger.htm">Software engineering is too big</a>, so you can&#39;t possibly know it all, so inevitably you&#39;ll meet people who know more than you. One of the dumbest thoughts that ever crossed my mind as a younger consultant was &quot;everybody asks me for help, but I don&#39;t need to ask anyone else - I must be doing great&quot;. Ah, the cluelessness of being young. </li><li>&quot;If you don&#39;t like people or don&#39;t believe in them, you won&#39;t be able to fake it&quot; (pg. 104). Tim&#39;s translation: &quot;People can tell when you think they&#39;re a moron.&quot;</li><li>&quot;Caring for people should precede confronting people&quot; (pg. 107)</li><li>&quot;Quitting is a permanent solution to a temporary problem.&quot; (pg 111)</li><li>&quot;Most of the time when you confront people, they will have an emotional reaction.&quot; (pg. 114)</li><li>&quot;Most people hate confrontation, but they love resolution.&quot; (pg. 115)</li><li>&quot;If you are not honest with yourself, you will not be capable of honest with others.&quot; (pg. 126) - Example: If you deceive yourself into thinking the big task will be done in only 4 days, you&#39;re going to struggle giving accurate status reports to management.</li><li>&quot;It is more rewarding to resolve a situation than to dissolve a relationship.&quot; (pg. 132)</li><li>Quoting someone else: &quot;If you make every game a life-and-death proposition... you&#39;ll be dead a lot.&quot; (pg. 138)</li><li>Quoting someone else: &quot;A successful man in one who can lay a firm foundation with the bricks others have thrown at him&quot; (pg. 222)</li><li>&quot;People are an appreciating asset only if we are willing to invest in them.&quot; (pg. 233)</li></ul><p>See also:</p><p><a href="/book_making_things_happen.htm" class="blogtitle">BOOK: Making Things Happen</a>, <a href="/book_bringing_out_the_best_in_people.htm" class="blogtitle">BOOK: Bringing Out the Best in People</a></p>]]></description><category>people</category><category>books</category></item><item><title>Four tool approaches to automated web UI tests</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/four_tool_approaches_to_automated_web_ui_tests.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/four_tool_approaches_to_automated_web_ui_tests.htm</link><pubDate>Fri, 29 Jan 2010 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=four%5Ftool%5Fapproaches%5Fto%5Fautomated%5Fweb%5Fui%5Ftests</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[&nbsp;We all know that in the ideal world, our web apps would have &quot;sufficient&quot; automated tests. But how? I&#39;m not an expert here, but I&#39;ve come across four general strategies: <table border="1" cellpadding="2" width="100%" style="border-collapse: collapse" bordercolor="#111111"><tbody><tr><td width="24%" bgcolor="#c0c0c0"><strong>Description</strong></td><td width="11%" bgcolor="#c0c0c0"><strong>Example</strong></td><td width="39%" bgcolor="#c0c0c0"><strong>PRO</strong></td><td width="25%" bgcolor="#c0c0c0"><strong>CON</strong></td></tr><tr><td width="24%" valign="top">Send web requests, and then parse the corresponding response.</td><td width="11%" valign="top">MSTest <a href="/an_easy_way_to_hack_unvalidated_web_input.htm">WebTests</a></td><td width="39%" valign="top"><ul><li>Handles simple postbacks very well</li><li>Independent of server technology (you don&#39;t care if it&#39;s ASPX, JSP, or PHP providing the responses back)</li><li>Lots of Visual Studio support</li></ul></td><td width="25%" valign="top"><ul><li>Dies on Ajax because it can&#39;t parse JavaScript</li><li>Requires a ton of parsing logic. Granted, there are free Html parsers to help with this.</li><li>Requires the expensive version of Visual Studio for Testers, so not everyone can run on their machines unless management pays $$$ for the licenses.</li></ul></td></tr><tr><td width="24%" valign="top">Directly tap into the ASPX pipeline (I&#39;m no expert here, but to my limited knowledge, it seemed different than merely the request-response model).</td><td width="11%" valign="top"><a href="/read/1034115.htm">NUnitAsp</a> (but this <a href="http://nunitasp.sourceforge.net/">was officially ended</a>)</td><td width="39%" valign="top"><ul><li>Minimizes the parsing</li><li>Free</li></ul></td><td width="25%" valign="top"><ul><li>Still trouble with JavaScript (if memory serves me right).</li></ul></td></tr><tr><td width="24%" valign="top">Recording and playing back the mouse and keyboard movements</td><td width="11%" valign="top">Don&#39;t know offhand, but I&#39;ve heard of them with COM+</td><td width="39%" valign="top"><ul><li>Tests actual UI layout (is the textbox 10 pixels below the button).</li></ul></td><td width="25%" valign="top"><ul><li>Very brittle with browsers, especially because browsers can resize</li></ul></td></tr><tr><td width="24%" valign="top">Run the browser in an automated script.</td><td width="11%" valign="top"><a href="http://watin.sourceforge.net/">WatiN</a></td><td width="39%" valign="top"><ul><li>Because it runs the browser itself, it can handle whatever the browser handles, like JavaScript. This is huge in today&#39;s Ajax world.</li><li>Free! This is great when you want the entire team to run it on their local machines.</li><li>Active community supporting it</li></ul></td><td width="25%" valign="top"><ul><li>(I believe, but may be wrong) that because it runs the browser, it&#39;s limited to just IE.</li></ul><p>&nbsp;</p></td></tr></tbody></table><p>Personally, I&#39;ve seen the best luck with WatiN. Especially in the Ajax age, automated tests need to run JavaScript. I also find that to get a team to adopt a new tool, it&#39;s invaluable to let them run it themselves (i.e. anyone can download the open-source tool and run it with management paying $$$ for a license), and to provide tutorials (i.e. WatiN has an active community).</p><p>&nbsp;</p>]]></description><category>testing</category><category>aspnet</category></item><item><title>Is this code broken?</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/is_this_code_broken.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/is_this_code_broken.htm</link><pubDate>Mon, 25 Jan 2010 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=is%5Fthis%5Fcode%5Fbroken</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>What constitutes broken code? Everyone agrees that code that crashes in production and threatens to have developers fired is indeed broken. But where&#39;s the line? Is the following code broken:</p><ul><li>The code logs incorrect data in an error log file?</li><li>The code displays incorrect values in a label (like a mis-formatted date)?</li><li>If a certain rare case occurs (like a button is pressed at exactly 12:00AM, or an uploaded file size is <em>exactly </em>1.00 MB), then the code crashes?</li><li>The code has mis-leading names for variables and methods. For example, it has a method &quot;IsNumber&quot; that checks only for integers, or &quot;IsLetter&quot; that allows for special characters? Say the current program calls the method with correct data so that the app never crashes?</li></ul><p>In all these cases, say the application essentially &quot;works&quot; and handles the main use cases.</p><p>The problem is maintenance. Maintaining and extending code is an expensive part of the total cost of ownership. You could spend <em>hours </em>tracking down <a href="/five_hours_for_one_line_of_code.htm">a single erroneous line of code</a>. Code that is low quality (tons of copy &amp; paste, misnamed methods, misleading logic, etc...) is going to be a fortune to maintain. On the other hand, certain functional errors that have zero impact on the business can perhaps be documented as &quot;known-issues&quot; (i.e. the month is formatted in a label with a preceding zero like &quot;03&quot; instead of just &quot;3&quot;.</p><p>I&#39;d say it comes down to the business, and the code is broken if it <a href="/book_complete_mba_for_dummies.htm">costs the business</a> more than it should - whether it be via maintenance costs or functional errors that hinder the end users. Perhaps the question isn&#39;t as much &quot;is this code broken&quot;, but &quot;how can we maximize the business-value of this code?&quot;</p>]]></description><category>coding</category></item><item><title>Five Ironies of Unit Testing</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/five_ironies_of_unit_testing.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/five_ironies_of_unit_testing.htm</link><pubDate>Thu, 21 Jan 2010 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=five%5Fironies%5Fof%5Funit%5Ftesting</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>I am a huge advocate of unit testing. After years of writing tests, and encouraging other devs to write tests, I find five common ironies:</p><ol><li>The devs who would most benefit from unit tests are the devs who are least likely to write them - and vice versa. The star devs, who would write the code correctly to begin with, are also the ones most open to unit testing. Likewise, the low-quality-code-developers who shun testing are the one&#39;s whose code could benefit the most from it.</li><li>Writing <a href="/would_you_still_write_unit_tests_even_if_you_couldnt_automa.htm">unit tests actually <em>saves</em> time</a> - not just in integration testing but also in development - because it stubs out the context, allowing you to immediately jump to the area that needs testing instead of spending 5 minutes setting up the scenario.</li><li>Developers often punt on unit testing because &quot;my manager doesn&#39;t support it&quot;, but unit testing is really an encapsulated development detail that <a href="/backwards_i_wanted_to_do_unit_tests_but_my_manager_wouldnt_l.htm">doesn&#39;t need managerial support</a> (although of course their support is appreciated).</li><li>Many devs generate the unit tests <em>after</em> they write the code (&quot;those ivory-tower architects said we needed tests&quot;), but tests are most beneficial <em>before</em> you write the code because they force you to think what the code does, and they make it faster to write the code.</li><li>The same teams who don&#39;t want to write unit tests are relieved to have such tests on the code they need to maintain.</li></ol><p>&nbsp;</p>]]></description><category>testing</category></item><item><title>Blogging as a Legacy</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/blogging_as_a_legacy.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/blogging_as_a_legacy.htm</link><pubDate>Tue, 19 Jan 2010 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=blogging%5Fas%5Fa%5Flegacy</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>I was casually chatting with a dev manager who had worked in the trenches for 25 years. He emphasized how a lot of developers spend their career without leaving a legacy. You work on a dozen systems, for different companies, and a decade later don&#39;t have anything <em>external </em>to show for it. Sure, you&#39;ve got skills, 10-linear feet of obsolete tech books you&#39;ve read, and the memories. But it&#39;s not as tangible as shipping actual products (like the devs who can say &quot;I helped ship <a href="/10_rules_that_age_of_empires_teaches_about_development.htm">AoE2</a> - that was me!&quot;).</p><p>This hit home with me as I reach the 5-year mark for my blog. After 5 years of consistent blogging, I&#39;ve written 430 posts and received hundreds of comments (many of them educating to me). There are a lot of obvious <a href="/the_benefits_of_technical_blogging.htm">benefits to blogging</a>, but after writing for years, what really sticks out to me is the <em>legacy</em> of blogging. I started blogging at CSC, blogged all through Paylocity, and continue blogging now at CareerEd. Ironically, my blog topics have evolved from hard-core development, to tech lead, to architecture, to more <a href="/tags/?/management">managerial-related</a> tasks.</p><p>I can&#39;t show people any of the systems I&#39;ve done (except for the occasional screenshot from a dusty tech doc), but as appropriate, I can share with them the <a href="/read/page/archive.htm">archive of hundreds</a> of blog posts. It helps motivate me to want to write for another 5 years.</p>]]></description><category>misc</category></item><item><title>Three basic communication tips</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/three_basic_communication_tips.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/three_basic_communication_tips.htm</link><pubDate>Fri, 15 Jan 2010 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=three%5Fbasic%5Fcommunication%5Ftips</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>I am certainly no communication or &quot;people&quot; expert, which is probably why wiser people in my life have explicitly offered me three good rules for communicating with others. I think these rules apply in the corporate world as well, so it makes a good blog post (because I can&#39;t just blog about <a href="/tags/?/life">normal life-issues</a> unless I can somehow apply it to software engineering).</p><p><strong>Connect the dots </strong>- In software programming, we must explicitly spell every step. Sure you can refactor and abstract things out, or use third-party software to spare you from writing it - but somehow, every step must be flushed out in detail. This is great for a robust program, but it will drive real people insane (i.e. managers, business analysts, customers, and executives who write your paycheck). They&#39;ll just think you&#39;re being clueless, are inexperienced, or a <a href="/smart_vs_smart_aleck.htm">smart aleck</a>. When dealing with actual people, we need to be able to use our background knowledge of the situation to connect the dots. </p><p><strong>Don&#39;t wait to be asked -</strong> It takes effort to ask for something, and people don&#39;t like exerting effort, so anytime you can &quot;just know&quot; and do the right thing (perhaps because you know the bigger picture of what they&#39;re trying to do), people are going to appreciate it.</p><ul><li>For example, say you see a simple bug in the code. It&#39;s a safe change and the release isn&#39;t for a while. The savvy developer doesn&#39;t need to ask their manager &quot;can I fix this bug&quot; - they just do it (and maybe submit a ticket if their company&#39;s process requires that). Often just making the fix can be quicker than asking. (Of course common sense applies, don&#39;t go &quot;fixing&quot; mission-critical production code that&#39;s out of your scope).</li><li>It seems like only junior resources ask &quot;What can I do to help?&quot;- the senior ones already know.</li></ul><p>Of course, it&#39;s reasonable to pro-actively notify a manager &quot;I see A, B, and C. I know you&#39;re busy, so I&#39;ll assume I should start working on &#39;B&#39; first because of reasons XYZ. Just let me know if you&#39;d like to switch tasks&quot;. This lets your manager reply with a 1 word email like &quot;great&quot;, and managers like being able to delegate entire tasks with 1-word emails.</p><p>&quot;Connecting the dots&quot; and &quot;Don&#39;t wait to be asked&quot; are related. Think of this as not needing to be micromanaged.</p><p><strong>Translate what people say. </strong>There is a world of difference between someone&#39;s words and what they actually mean. Whether they&#39;ve made a simple typo, using poor word choice, or they&#39;re struggling to articulate something - it&#39;s a big personal win if you can &quot;see the forest through the trees&quot; and know what they mean. You can do this by leveraging context, know where they&#39;re trying to go, and having familiarity with what it takes to get there.</p><ul><li>Example: Missing words - A non-technical manager may say &quot;we need to store this dropdown control in the database&quot;. They probably mean &quot;..store <em>the value of</em> this dropdown control...&quot;</li><li>Example: Wrong words - A non-technical manager says &quot;We need a bigger machine&quot;. They probably mean &quot;we need a <em>better-performing </em>machine&quot;</li></ul><p><strong>Summary</strong></p><p>You might say &quot;but this isn&#39;t fair - I was doing my job to the &#39;T&#39;, I was technically correct&quot; Ah, but life is not fair. You can be right, or you can be happy. And (as I find out the hard way) if you want to be happy with other people, you&#39;re eventually need to master many things, including these three.</p><p>&nbsp;</p>]]></description><category>management</category></item><item><title>BOOK: Complete MBA for Dummies</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/book_complete_mba_for_dummies.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/book_complete_mba_for_dummies.htm</link><pubDate>Mon, 11 Jan 2010 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=book%5Fcomplete%5Fmba%5Ffor%5Fdummies</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>I&#39;m always been intrigued by the <a href="/coding_is_just_the_tip_of_the_iceberg.htm">non-coding aspects</a> of a project that are necessary for that project to succeed. Much of this includes people and business skills. I keep hearing of co-workers who take business classes, and it sounds fun, but it takes more time than I have right now (building <a href="/real_life_copying_code_is_easier_than_copying_snow_dinosaur.htm">snow-dinosaurs</a>, <a href="/real_life_avoiding_customization_to_build_a_sandbox.htm">sandboxes</a>, and <a href="/real_life_taking_down_the_christmas_lights_and_project_fail.htm">Christmas lights</a> for the kids takes a lot of time). So I settled for the next best thing: reading the <strong><a href="http://www.amazon.com/Complete-Dummies-Business-Personal-Finance/dp/0470194294/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1262917294&amp;sr=1-1">Complete MBA for Dummies</a></strong>. I was impressed.</p><p>The book is a casual 400-page read, and certainly lives up the the &quot;for dummies&quot; genre. It offers an overview of starting a small business, from the basics of management to HR to accounting to marketing and economics. I liked the practical tone.</p><p>While a book like this doesn&#39;t fundamentally change one&#39;s view of business, it is useful to get one to casually think about business-concepts during the normal work day. For each project, it prompts me to ask questions like:</p><ul><li>&quot;where does the revenue come from?&quot;</li><li>&quot;who is paying for this project?&quot;</li><li>&quot;how will this project help the <em>business</em>?&quot;</li><li>&quot;can this thing I built actually be marketed?&quot;</li><li>&quot;who are the customers for this product?&quot;</li></ul><p>Continually keeping these types of questions in mind also helps a developer relate to business-sponsors, who are the people that ultimately write the developer&#39;s paycheck.</p><p>&nbsp;</p>]]></description><category>management</category><category>books</category></item><item><title>Coding is just the tip of the iceberg</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/coding_is_just_the_tip_of_the_iceberg.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/coding_is_just_the_tip_of_the_iceberg.htm</link><pubDate>Fri, 08 Jan 2010 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=coding%5Fis%5Fjust%5Fthe%5Ftip%5Fof%5Fthe%5Ficeberg</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>I love coding. The more I do software engineering, the more I realize that coding is just the tip of the iceberg. Consider tasks besides coding that are required for a successful project:</p><ul><li>Identifying a business problem such that business sponsors are willing to pay for the product</li><li>Recruit the team to build the project</li><li>Provide the team the tools to develop the app (hardware &amp; software)</li><li>Collecting business requirements</li><li>Coordinating with business partners, such as those providing data that the product will use</li><li>Designing a functional spec</li><li>Creating the architectural and technical designs</li><li>Decide on build vs. acquire (buy, open-source)</li><li>Outsource part of the project</li><li>Managing the project</li><li>Procuring the physical infrastructure that the app is deployed on</li><li>QA testing the app (functional, integration, user-acceptance, performance, etc...)</li><li>Deploying the app</li><li>Write training manuals for the app</li><li>Training support staff and users</li><li>Marketing the app such that people actually use it</li><li>Supporting the app</li></ul><p>From start to finish, actually coding for a project may only be 5% - 10% of the total effort. That means that there&#39;s a huge portion of the project that is non-coding, and that huge portion can often overcome difficult coding tasks.</p><p>For example, say there is a component that is just difficult to program (it&#39;s complex, it&#39;s big, it occurs outside your expertise, etc...) You could possibly get around coding it yourself by maybe:</p><ul><li>Buying or open-sourcing it (example: use an open-source tool or class library from CodePlex instead of writing it yourself)</li><li>Training the internal end users around using that feature (&quot;we know the website has a bug, but just don&#39;t click the browser back button&quot;)</li><li>Using project management to get it punted, or out of scope</li><li>Convincing the business sponsor that the feature is not needed (&quot;we don&#39;t need to invest all that time making a dancing paper clip assistant&quot;)</li><li>Better hardware (example, upgrading hardware for better performance)</li></ul><p>The stars who keep delivering successful projects are familiar with this, and they are constantly mitigating challenges in one task by giving up something that doesn&#39;t matter from another task.</p><p>Sometimes you can solve hard coding problems by just sheer skill and coding right through it. But it&#39;s good to be aware of other techniques to work around the problem altogether.</p>]]></description><category>management</category></item><item><title>Estimating database table sizes using SP_SpaceUsed</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/estimating_database_table_sizes_using_sp_spaceused.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/estimating_database_table_sizes_using_sp_spaceused.htm</link><pubDate>Mon, 28 Dec 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=estimating%5Fdatabase%5Ftable%5Fsizes%5Fusing%5Fsp%5Fspaceused</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>One of Steve McConnell&#39;s tips from his great book on estimating (<a href="/book_software_estimation_demystifying_the_black_ar.htm">Software Estimation: Demystifying the Black Art</a>) is that you should not estimate that which you can easily count. Estimating database table sizes is a great example of this. Sure, on one hand disk space is relatively cheap; on the other hand you want to know at least a ballpark estimate of how much space your app will need - will database size explode and no&nbsp; longer fit on your existing SAN?</p><p>Here&#39;s a general strategy to estimate table size:</p><p><strong>1. Determine the general schema for the table</strong></p><p>Note the column datatypes that could be huge (like varchar(2000) for notes, or xml, or blob)</p><p><strong>2. Find out how many rows you expect the table to contain</strong></p><p>Is the table extending an existing table, and therefore proportional to it? For example, do you have an existing &quot;Employee&quot; table with 100,000 records, and you&#39;re creating a new &quot;Employee_Reviews&quot; table where each employee has a 2-3 reviews (and hence you&#39;re expecting 200,000 - 300,000 records)? If the table is completely new, then perhaps you can guess the rowcount based on expectations from the business sponsors.</p><p>If the table has only a few rows (perhaps less than 10,000 - but this depends), the size is probably negligible, and you don&#39;t need to worry about it.</p><p><strong>3. Write a SQL script that creates and populates the table.</strong></p><p>You can easily write a SQL script to create a new table (and add its appropriate indexes), and then use a WHILE loop to insert 100,000 rows. This can be done on a local instance of SQL Server. Note that you&#39;re not inserting the total number of rows you estimated -&nbsp; i.e. if you estimated that table will contain 10M rows, you don&#39;t need to insert 10M rows - rather you&#39;ll want a &quot;unit size&quot;, which you can then multiple by however many rows you expect. (Indeed, you don&#39;t want to wait for 10M rows to be inserted, and your test machine may not even have enough space for that much test data).</p><p>For variable data (like strings), use average sized data. For null columns, populate them based on how likely you think they&#39;re be used, but err on the side of more space.</p><p>Obviously, save your script for later.</p><p><strong>4. Run SP_SPACEUSED</strong></p><p><a href="http://msdn.microsoft.com/en-us/library/ms188776(SQL.90).aspx">SP_SpaceUsed</a> displays how much data a table is using. It shows results for both the data, <em>as well as the indexes</em> (never forget the index space).</p><p>You can run it as simply as: </p><blockquote><p>exec SP_SPACEUSED &#39;TableTest1&#39;</p></blockquote><p>Now you can get a unit-size per row. For example, if the table has 3000KB for data, and 1500KB for indexes, and you inserted a 100K rows, then the average size per row is: (3000KB + 1500KB) / 100,000. Then, multiple that by however many rows you expect.</p><p>This may seem like a lot of work, and there are certainly ways to theoretically predict it by plugging into a formula. My concern is that it&#39;s too easy for devs to miscalculate the formula (like forgetting the indexes, not accounting the initial table schema itself, or just all the extra steps) </p><p><strong>5. Estimate the expected growth</strong></p><p>Knowing the initial size is great, but you also must be prepared for growth. We can make educated guesses based on the driving factors of the table size (maybe new customers, a vendor data feed, or user activity), and we can then estimate the size based on historical data or the business&#39;s expectations. For example, if the table is based on new customers, and the sales team expects 10% growth, then prepare for 10% growth. Of if the table is based on a vendor data feed, and historically the feed has 13% new records every year, then prepare for 13% growth.</p><p>Depending on your company&#39;s SAN and DBA strategy, be prepared to have your initial estimate at least include enough space for the first year of growth.</p><p><strong>6. Add a safety factor</strong></p><p>There will be new columns, new lookup and helper tables, a burst of additional rows, maybe an extra index - <em>something </em>that increases the size. So, always add a safety factor.</p><p><strong>7. Prepare for an archival strategy</strong></p><p>Some data sources (such as verbose log records) are prone to become huge. Therefore, always have a plan for archival - even if it&#39;s that you can&#39;t archive (such as it&#39;s a transactional table and the business requires regular transactions on historical data). However, sometimes you get lucky; perhaps the business requirements say that based on the type of data, you only legally need to carry 4 years worth of data. Or, perhaps after the first 2 years, the data can be archived in a data warehouse, and then you don&#39;t worry about it anymore (this just passes the problem to someone else).</p><p><strong>Summary</strong></p><p>Here&#39;s a sample T-SQL script to create the table and index, insert data, and then call SP_SpaceUsed:</p><blockquote><p><font face="Courier New"><span><span class="kwrd"><font size="2">USE</font></span><font size="2"> [MyTest]<br /><span class="kwrd">GO</span><br /><br /><span class="kwrd">if</span> <span class="kwrd">exists</span> (<span class="kwrd">select</span> 1 <span class="kwrd">from</span> sys.indexes <span class="kwrd">where</span> [name] = <span class="str">&#39;IX_TableTest1&#39;</span>)<br />&nbsp;&nbsp;&nbsp; <span class="kwrd">drop</span> <span class="kwrd">index</span> TableTest1.IX_TableTest1<br /><br /><span class="kwrd">if</span> <span class="kwrd">exists</span> (<span class="kwrd">select</span> 1 <span class="kwrd">from</span> sys.tables <span class="kwrd">where</span> [name] = <span class="str">&#39;TableTest1&#39;</span>)<br />&nbsp;&nbsp;&nbsp; <span class="kwrd">drop</span> <span class="kwrd">table</span> TableTest1<br /><br />--=========================================<br />--Custom <span class="kwrd">SQL</span> <span class="kwrd">table</span><br /><span class="kwrd">CREATE</span> <span class="kwrd">TABLE</span> [dbo].[TableTest1](<br />&nbsp;&nbsp;&nbsp; [SomeId] [<span class="kwrd">int</span>] <span class="kwrd">IDENTITY</span>(100000,1) <span class="kwrd">NOT</span> <span class="kwrd">NULL</span>,<br />&nbsp;&nbsp;&nbsp; [phone] [bigint] <span class="kwrd">NOT</span> <span class="kwrd">NULL</span>,<br />&nbsp;&nbsp;&nbsp; [SomeDate] [datetime] <span class="kwrd">NOT</span> <span class="kwrd">NULL</span>,<br />&nbsp;&nbsp;&nbsp; [LastModDate] [datetime] <span class="kwrd">NOT</span> <span class="kwrd">NULL</span><br />) <span class="kwrd">ON</span> [<span class="kwrd">PRIMARY</span>]<br /><br />--<span class="kwrd">Index</span><br /><span class="kwrd">CREATE</span> <span class="kwrd">UNIQUE</span> <span class="kwrd">NONCLUSTERED</span> <span class="kwrd">INDEX</span> [IX_TableTest1] <span class="kwrd">ON</span> [TableTest1] <br />(<br />&nbsp;&nbsp;&nbsp; [SomeId] <span class="kwrd">ASC</span>,<br />&nbsp;&nbsp;&nbsp; [phone] <span class="kwrd">ASC</span><br />) <span class="kwrd">ON</span> [<span class="kwrd">PRIMARY</span>]<br />--=========================================<br /><br /><br />--do inserts<br /><br /><span class="kwrd">declare</span> @max_rows <span class="kwrd">int</span><br /><span class="kwrd">select</span> @max_rows = 1000<br /><br /><span class="kwrd">declare</span> @i <span class="kwrd">as</span> <span class="kwrd">int</span><br /><span class="kwrd">select</span> @i = 1<br /><br /><span class="kwrd">WHILE</span> (@i &lt;= @max_rows)<br /><span class="kwrd">BEGIN</span><br />&nbsp;&nbsp;&nbsp; --=============<br />&nbsp;&nbsp;&nbsp; --Custom <span class="kwrd">SQL</span> <span class="kwrd">Insert</span> (note: <span class="kwrd">use</span> <span class="kwrd">identity</span> <span class="kwrd">value</span> <span class="kwrd">for</span> uniqueness)<br />&nbsp;&nbsp;&nbsp; <span class="kwrd">insert</span> <span class="kwrd">into</span> TableTest1 (phone, SomeDate, LastModDate)<br />&nbsp;&nbsp;&nbsp; <span class="kwrd">select</span> 6301112222, getDate(), getDate()<br />&nbsp;&nbsp;&nbsp; --=============<br /><br />&nbsp;&nbsp;&nbsp; <span class="kwrd">select</span> @i = @i + 1<br /><br /><span class="kwrd">END</span><br /><br />--<span class="kwrd">Get</span> sizes<br /><span class="kwrd">exec</span> SP_SPACEUSED </font><span class="str"><font size="2">&#39;TableTest1&#39;</font></span></span></font></p></blockquote><blockquote><p>&nbsp;</p></blockquote>]]></description><category>management</category><category>sql</category></item><item><title>How not to estimate</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/how_not_to_estimate.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/how_not_to_estimate.htm</link><pubDate>Mon, 14 Dec 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=how%5Fnot%5Fto%5Festimate</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[Being responsible for the end-to-end solution really makes me think about <a href="/book_software_estimation_demystifying_the_black_ar.htm">how to estimate</a>. The flipside is that it also makes me think about how<em> not</em> to estimate: <ol><li><strong>Wild guess</strong> - sometimes this seems like your only option, but most of the time there is ways to improve on the guess (base it on similar projects, or split it into components and estimate those individually).</li><li><strong>What you think the boss wants to hear</strong> - This may seem like the easy way to initially win favor with the boss, but it will come back with a vengeance when the estimate drastically deviates from reality. Also, because the boss always <em>wants </em>to hear lower schedule times, this has a huge bias that will send you off course.</li><li><strong>Base it on unrelated projects </strong>- Historical data is great, but don&#39;t compare apples to oranges. That a WinForm app took 3 months tells you almost nothing about how long an ASP.Net app will take.</li><li><strong>Pick an arbitrary big number</strong> - During crunch time, it&#39;s easy to think that everything will magically be better &quot;next week&quot; or &quot;next month&quot; (&quot;that will give us <em>enough</em> time to fix everything),&nbsp; but then that time rolls around and the project is still behind schedule.</li></ol><p>All of these are bad estimation methods because they miss the fundamental point - how long will the project <em>really</em> take to build in the <em>real</em> world? Wild guesses or the boss&#39;s wishes are not necessarily grounded in reality, so basing estimates on them is barking up the wrong tree.</p><p>I realize it&#39;s easy to say &quot;how not to do something&quot;. I&#39;d recommend Steve McConnell&#39;s book, <a href="/book_software_estimation_demystifying_the_black_ar.htm">Software Estimation: Demystifying the Black Art</a>, for how to do a great job of estimating.</p><p>&nbsp;</p>]]></description><category>management</category></item><item><title>BOOK: 97 things every software architect should know</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/book_97_things_every_software_architect_should_know.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/book_97_things_every_software_architect_should_know.htm</link><pubDate>Sat, 28 Nov 2009 19:05:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=book%5F97%5Fthings%5Fevery%5Fsoftware%5Farchitect%5Fshould%5Fknow</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>A few months back I finished the book <a href="http://www.amazon.com/Things-Every-Software-Architect-Should/dp/059652269X/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1259434287&amp;sr=1-1">97 Things Every Software Architect Should Know</a>. I&#39;ve been slow on blogging, so I hadn&#39;t gotten around to my standard follow-up post for books I read.</p><p>The books consists of 97 short essays, by various accomplished architects, each with a quick insight. It was a casual and fun read, the kind of book that&#39;s easy to sneak in a few pages between changing the kids diapers and fixing the house. It&#39;s got a lot of good points. I especially recall an essay about how &quot;the database is your fortress&quot; - GUI and Middle Tier apps change, but you will <em>always</em> have your database. </p><p>For hard-core architecture, I thought that <a href="/book_microsoft_net_architecting_applications_for_the_ente.htm" class="blogtitle">Microsoft .NET: Architecting Applications for the Enterprise</a> and <a href="/book_patterns_of_enterprise_application_architecture.htm" class="blogtitle">Patterns of Enterprise Application Architecture</a> were much more systematic and thorough. But overall, it was still a fun read.</p>]]></description><category>books</category></item><item><title>Can you still be technical if you don&apos;t code?</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/can_you_still_be_technical_if_you_dont_code.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/can_you_still_be_technical_if_you_dont_code.htm</link><pubDate>Fri, 09 Oct 2009 12:28:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=can%5Fyou%5Fstill%5Fbe%5Ftechnical%5Fif%5Fyou%5Fdont%5Fcode</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>Can you still be technical if you don&#39;t code? A lot of developers have a passion for the technology, do a great job in their current role of implementing solutions (which requires coding), and then get &quot;promoted&quot; into some &quot;big picture&quot; role that no longer does implementation - ironically the thing they did so well at. These higher-level roles often do lots of non-trivial things, but not actual coding. For example:</p><ul><li>Infrastructure (Servers, SAN space, database access, network access)</li><li>Design decisions</li><li><a href="/book_working_effectively_with_legacy_code.htm">Dealing with legacy code</a></li><li>Handling outsourcing, insourcing, consultants</li><li>Build-vs-buy</li><li>Vendor evaluations/score card; integrate the vendor&#39;s product into your own</li><li>Coordinate large-scale integration of many apps from different environments</li><li>Coordination among multiple product life cycles</li><li>Writing guidance docs</li><li><a href="/code_reviews__objections_and_counterobjections.htm">Code reviews</a></li><li>Occasional prototypes</li><li><a href="/coding_vs_configuration.htm">Configuration</a></li></ul><p>On one hand, these types of tasks require technical knowledge in that you wouldn&#39;t expect a non-technical person to perform them. On the other hand, they don&#39;t seem in the same category as hands-on coding.</p><p>What do you think - can you be technical (or remain technical) without actually writing code?</p>]]></description><category>coding</category></item><item><title>Reasons to NOT put version history in the comments</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/reasons_to_not_put_version_history_in_the_comments.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/reasons_to_not_put_version_history_in_the_comments.htm</link><pubDate>Tue, 06 Oct 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=reasons%5Fto%5Fnot%5Fput%5Fversion%5Fhistory%5Fin%5Fthe%5Fcomments</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[Some coding standards ask that developers add revision history to the top of the method. Not just the normal &quot;Summary&quot; and &quot;Parameter&quot; tags that can be used to automatically create documentation, but rather a full blown revision log with developer name, date, and comment. This was bigger in the 80&#39;s and 90&#39;s, when source control and refactoring weren&#39;t as common. However, in these days, putting revision history in your comments has some really big problems: <ul><li><strong>Extra effort - </strong>It requires extra effort from developers, and usually the tedious kind of effort. It requires manual developer discipline, so architects don&#39;t have a good way to enforce this.</li><li><strong>Bad for refactoring - </strong>It discourages refactoring of methods. Say you split a method in two - how do you split up the commented version history? </li><li><strong>Source control already provides this -</strong> It doesn&#39;t tell you anything that source control history won&#39;t already give you. But even worse, it could be misleading - source control is the true authority, a developer could accidentally type (or forget) the wrong comments. Also, by documenting at the top of the method, it is hard to indicate what changed in the middle (whereas source control diff would instantly tell you).</li></ul><p>Perhaps for SQL, I can see the benefit, so that when the DBA runs sp_helptext on a stored proc, they get a quick history (and databases aren&#39;t usually refactored like C# code). However, for middle tier code, putting revision history in comments seems like an unwise use of time.</p><p>LINK: <a href="/comments_as_version_control.htm" title="read entry">Comments as version control</a><br />&nbsp;</p>]]></description><category>style</category></item><item><title>What makes something Enterprise?</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/what_makes_something_enterprise.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/what_makes_something_enterprise.htm</link><pubDate>Fri, 02 Oct 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=what%5Fmakes%5Fsomething%5Fenterprise</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>There&#39;s a world of difference between a prototype hammered out over a weekend, and an enterprise app ready for the harsh world of production. Here&#39;s a somewhat random brainstorm. In general (there&#39;s always an exception), Enterprise apps:</p><ul><li>Are scalable - they handle large loads and can be called many times.</li><li>Have a retry strategy - for example, it tries pinging the external service three times before &quot;failing&quot;.</li><li>Have a failover strategy, like an active-passive machine cluster for maximum uptime, and a disaster recovery site.</li><li>Send notifications.</li><li>Handles invalid data (like <a href="/the_addresss_state_field_may_contain_more_than_just_the_50_.htm">states</a>, <a href="/how_zip_codes_can_get_complicated.htm">zip codes</a>, and <a href="/what_is_a_number.htm">numbers</a>).</li><li>Can integrate with other systems (perhaps providing web service wrappers, or command line APIs, or publicly accessible data repositories that other apps can modify) .</li><li>Are deployable - &quot;it works on my machine&quot; absolutely does not cut it.</li><li>Have Logging - this is especially useful for debugging in production, or measuring how many errors (and which types) are thrown.</li><li>Have long-running process (hours, days, or even weeks) - not just a single thread in memory.</li><li>Have async processes, which usually means concurrency and threading problems.</li><li>Support multiple instances of the app running. You can open two copies of word, or run two MSBuild scripts at the same time.</li><li>Handle product versioning.</li><li>Care about the hardware it&#39;s running on (enough CPU and memory).</li><li>Have a pluggable architecture - You may need to switch data providers (Oracle/SQL/Xml).</li><li>Have external data sources (web services, ftp file dumps, external databases).</li><li>Can scale out, such as adding more web servers, or splitting the database across multiple servers.</li><li>Have security constraints (both hacking, and functional).</li><li>Have process that are documented (not just for training, but also for legal auditing and compliance issues).</li></ul><p>Much of this code isn&#39;t the fun, &quot;glamorous&quot; stuff. However, it&#39;s this kind of robustness that separates the &quot;toys&quot; from the enterprise workhorses.</p><p>See also: <a href="/23_features_of_an_enterprise_data_access_layer_1.htm">Enterprise Data Access</a>, <a href="/a_quick_overview_of_enterprise_object_caching.htm">Enterprise Caching</a></p>]]></description><category>architecture</category></item><item><title>A quick overview of enterprise object caching</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/a_quick_overview_of_enterprise_object_caching.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/a_quick_overview_of_enterprise_object_caching.htm</link><pubDate>Wed, 30 Sep 2009 13:43:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=a%5Fquick%5Foverview%5Fof%5Fenterprise%5Fobject%5Fcaching</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>Caching is a performance mechanism where you store an expensive-to-create value for future consumption. For example, you may cache dropdown values to spare yourself expensive database hits. Caching is one of those buzzwords that everyone knows your application should have, but surprisingly few really do.</p><p>Books have been written on caching, so this is just a quick brain dump based on my personal experiences. Also note that I refer to &quot;the database&quot; a lot because it&#39;s the main data dependency that most developers can relate to, but really, it could be anything (web service, external file, etc...).</p><p><strong>Frontend and Backend Caching</strong></p><table border="1" cellpadding="2" width="100%" style="border-collapse: collapse" bordercolor="#111111"><tbody><tr><td width="33%">&nbsp;</td><td width="33%"><strong>Frontend UI</strong></td><td width="34%"><strong>Backend</strong></td></tr><tr><td width="33%">Where is it located?</td><td width="33%">Local (in process)</td><td width="34%">Remote (external machines)</td></tr><tr><td width="33%">Pro</td><td width="33%">Faster because it&#39;s local - no remote hit</td><td width="34%">Handles updating stale data in distributed systems <p>Handles any CLR serializable object, independent of the UI layer.</p></td></tr><tr><td width="33%">Con</td><td width="33%">Does not handle updating values - data may be stale <p>Limited to just HttpContext.</p></td><td width="34%">Slower because it&#39;s remote - you still need to pay for the remote hit.</td></tr><tr><td width="33%">Example</td><td width="33%">Asp.Net HttpContext.Cache</td><td width="34%"><a href="http://www.danga.com/memcached/">Memcache</a>, Velocity, others...</td></tr></tbody></table><p>Obvious follow-up question: &quot;Would you double cache something, taking data from the backend cache and saving it to the fronend cache?&quot; Sure, if it benefited your specific scenario. Ideally the backend cache is totally encapsulated anyway, so your frontend UI developer wouldn&#39;t even know if the data they&#39;re working with came from a cache or not.</p><p><strong>What is a good candidate for caching?</strong></p><p>Any data that:</p><ul><li>Takes a lot of time to create, either due to a remote hit (to a database or web service), or a large calculation time (like querying a million rows).</li><li><p>Has a small final result - you query a million rows just to return a single value.</p></li><li><p>Does not change - the problem with caching is stale data.</p></li><li><p>Has minimal dependencies. If your object touches 10 tables for creation, then there&#39;s a much greater chance of it becoming stale. This is one benefit of loosely coupled (and then batched) objects, instead of spaghetti code.</p></li><li><p>Has many reads, but very few writes. For example, system-level data (that everyone constantly requests) is good for caching, but employee-level data may not be.</p></li><li><p>Is retrieved externally and requires high uptime - for example you make a web service call to get some value, you call the service again 5 minutes later, the service is down, and you really wish you had even a &quot;stale&quot; copy of that data.</p></li></ul><p>The canonical example would be something like city-state dropdowns. Say it&#39;s initially a remote database hit to some &quot;City/State&quot; tables, it returns a small amount of data, it changes infrequently (The US has had 50 states for the last half-century), so it&#39;s read many times but not prone to stale data.</p><p>What is a bad candidate for caching? Pretty much, the opposite of the good criteria.</p><p><strong>Pitfalls with caching</strong></p><p>Merely creating the dictionary isn&#39;t the problem. The problem will be integrating it (seamlessly) into your data persistence layer, and then ensuring the cache doesn&#39;t become stale - <em>especially</em> across a distributed environment - and then making sure it actually improves your performance instead of degrading it.</p><p>Stale data is <em>the</em> bane of caching. There are at least a few ways to deal with stale data:</p><ul><li>Apply a time-out policy such that all data expires after N minutes, but that won&#39;t be acceptable for most scenarios.</li><li>If your app is changing the data (such as updating a details page), then have the DAL method (that calls the update SQL) also ping the cache to clear the stale object. This requires that your application somehow keeps track of which objects depend on which piece of data. It works great with a domain model, which requires more design upfront, but can have huge payoffs.</li><li>If someone else is directly changing the database, such as a DBA running ad-hoc SQL in production, then consider providing some admin console that lets them clear segments of the cache. For example, if the DBA did a mass-update of all salaries, then have the admin page allow you to flush all salary-related objects out of the cache. This requires some infrastructure for tagging each cached object (perhaps a master config file), and discipline from the DBA to check that admin page.</li><li>Beware of &quot;database cache dependencies&quot; (ASP.Net 2.0?), that claim to let you apply triggers to the database table, and then automatically clear the appropriate cache items when a specific row/column is updated. I&#39;ve personally never gotten this to successfully work, have heard lots of horror stories (especially when deploying it across a DMZ), and it forces the domain design into the database instead of the middle tier. Although I&#39;m all ears to anyone who&#39;s had a success story here.</li></ul><p>Some other things to keep in mind:</p><ul><li><p><strong>Where should my cache tie in?</strong> Ideally, you&#39;d want the backend cache abstracted <a href="/23_features_of_an_enterprise_data_access_layer_1.htm">via your dataAccess layer</a>. This becomes very feasible with CodeGeneration. Whether data is pulled from cache or the live database is just a tuning option. Just like you don&#39;t want to put in-line SQL throughout your codebehind pages, you probably don&#39;t want to tightly-couple all your UI code to your cache provider. The frontend cache can be referenced in your UI, but again, be aware of too much plumbing code that &quot;designs you into a corner&quot;.</p></li><li><p><strong>Only temporary</strong> - A cache is not a persistent data store, it is not merely a &quot;mirror&quot; to scale out your database, as you must account for the cache being cleared. A data access method should always have a means to recreate the cached data.</p></li><li><strong>Why use a remote cache?</strong> If both the cache and database servers both have remote hits, what&#39;s the difference? In its simplest form, this helps scale out the database (which is usually a bottleneck). Every hit on the cache is one less hit on the already-overloaded database. Even after the remote hit, the cache can have a much faster lookup time because while the cache stores a created object, the database may still need to query 1 million rows to collect the data.</li><li><p><strong>Control Panel</strong> - You&#39;ll want to provide an easy way to flush the entire cache, or even segments of the cache, without restarting any servers. It&#39;s also great moral support to have a statistics page showing how many thousand (million) database calls have been spared.</p></li><li><p><strong>Configuration</strong> - You&#39;ll want to provide a way to configure almost everything: the cache durations, what category of duration (short, medium, long), which objects get cached, and perhaps even turn off the entire cache for emergency troubleshooting. Caching is something that you want to tune based on actual production results. Ideally control of what gets cached is all abstracted to a few easy-to-manage config files. You do not want these config values hard-coded throughout your app.</p></li><li><p><strong>Beware of over-caching - </strong>If done the wrong way, caching can actually screw your performance. Say you cache something that is continually obsolete, so instead of just doing the normal database hit, you continually also need to do the extra cache query.</p></li></ul><p><strong>Good things to read</strong></p><p>There&#39;s an endless list of info on caching. Here are some that could be useful.</p><ul><li>The Pragmatic Programmers have a whole book on <a href="http://www.pragprog.com/titles/memcd/using-memcached">caching with memcached</a>! (I&#39;ve personally used <a href="http://www.danga.com/memcached/">Memcached</a> before, and liked it.)</li><li>MSDN: <a href="http://msdn.microsoft.com/en-us/library/ms978498.aspx">Caching Architecture Guide for .NET Framework Applications</a></li><li>Enterprise Library <a href="file:///C:/Projects/Net%20Articles/BlogIdeas/Caching%20Application%20Block">Caching Application Block</a></li></ul><p>Yes, there&#39;s ton more that can be said about caching. Again, this is just a quick brain dump.</p>]]></description><category>architecture</category></item><item><title>ConnectionTimeout vs. CommandTimeout</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/connectiontimeout_vs_commandtimeout.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/connectiontimeout_vs_commandtimeout.htm</link><pubDate>Wed, 23 Sep 2009 05:00:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=connectiontimeout%5Fvs%5Fcommandtimeout</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>SQL timeouts can be <em>very</em> annoying, especially for internal development tools where performance isn&#39;t critical.</p><p>A lot of developers will try fixing this by modifying the <a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectionstring(VS.71).aspx">connection string</a> by appending &quot;Connect Timeout=300&quot;. Normally this is easy because the connection string is stored in some config file.</p><p>However, it still usually fails. This is because there&#39;s a big difference between SqlConnection.<a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectiontimeout(VS.71).aspx">ConnectionTimeout</a> and SqlCommand.<a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.commandtimeout(VS.80).aspx">CommandTimeout</a>.</p><p>If you&#39;re running a command, like a snippet of SQL or a stored proc, then your code needs to set the <em>CommandTimeout</em>. Something like so:</p><blockquote><p><font face="Courier New" size="2">SqlConnection con = new SqlConnection(strDbCon);<br />SqlCommand cmd = con.CreateCommand();<br />cmd.CommandType = CommandType.Text;<br />cmd.CommandText = strText;<br /><strong>cmd.CommandTimeout = 10000;</strong> //no relation to con.ConnectionTimeout</font></p></blockquote><p>Obviously, that&#39;s very minimalist code, but that&#39;s the general idea. For a <a href="/23_features_of_an_enterprise_data_access_layer_1.htm">robust data access layer</a>, you&#39;d make the timeout configurable.</p>]]></description><category>coding</category><category>database</category></item><item><title>I don&apos;t have time to put on the parachute</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/i_dont_have_time_to_put_on_the_parachute.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/i_dont_have_time_to_put_on_the_parachute.htm</link><pubDate>Mon, 21 Sep 2009 14:01:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=i%5Fdont%5Fhave%5Ftime%5Fto%5Fput%5Fon%5Fthe%5Fparachute</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>If you&#39;re jumping out of a plane at 5000 feet - you take the time to put on the parachute. Sure, you could save yourself a few seconds, and for the first 1000 feet having that parachute doesn&#39;t matter yet when you&#39;re still free-falling (&quot;I saved schedule time by skipping the &#39;put-on-parachute&#39; task!&quot;). However, by the time you hit the ground, that parachute is life-saving.</p><p>Same thing with software projects and best practices. The project is like jumping out of a plane, and the best practices are like the parachute.&nbsp; Sure, some &quot;best practices&quot; are just useless marketing buzzwords. However, others - like unit testing - are the real deal. And a developer or manager who rejects unit testing (for new .Net code in the middle tier) because they &quot;don&#39;t have time&quot; is like jumping out of the plane without putting on your parachute. You save a bit of time upfront, but when the project goes to production and &quot;crashes&quot; into reality, the maintenance costs and untested boundary cases will kill it.</p><p>&quot;I don&#39;t have time&quot; sounds much more noble and business-like than &quot;I don&#39;t understand that idea&quot;, or &quot;I just don&#39;t feel like doing something new.&quot; But within the (very common) context of new .Net class-library development - given that testing frameworks are free (NUnit, MSTest), and that any developer can at least write their tests locally - <a href="/backwards_i_wanted_to_do_unit_tests_but_my_manager_wouldnt_l.htm">regardless of management support</a>, and that in certain scenarios it&#39;s actually <a href="/would_you_still_write_unit_tests_even_if_you_couldnt_automa.htm">faster to develop code by writing unit tests</a> (because it stubs out the context), the &quot;I don&#39;t have time&quot; reply to unit testing certain scenarios is misguided. Sure there are always exceptions, and reasons that <a href="/why_goodintentioned_devs_might_not_write_good_unit_tests.htm">good devs may not write unit tests</a>. Testing <a href="/creating_database_unit_tests_in_10_minutes.htm">databases</a>, or <a href="/book_working_effectively_with_legacy_code.htm">legacy code</a>, <a href="/part_of_the_problem_testing_ui_technologies_is_that_they_cha.htm">or the UI</a>, or integration is a different beast. However, in general, testing public methods in a C# class library, without external data dependencies, should be as reasonable as putting a parachute on while jumping out of a plane.</p>]]></description><category>testing</category></item><item><title>LCNUG - Sept 24 - C# 4.0</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/lcnug__sept_24__c_40.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/lcnug__sept_24__c_40.htm</link><pubDate>Thu, 17 Sep 2009 22:09:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=lcnug%5F%5Fsept%5F24%5F%5Fc%5F40</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>Mike Stall (MSFT) will present on the <a href="http://www.lcnug.org/events/09-09-08/LCNUG_September_24_C_4_0-4248649912.aspx">new features in C# 4.0</a>, including named and optional parameters, dynamic support, scripting, office interop and No-PIA (Primary-Interop-Assemblies) support.</p><p>This is a great event for those interested in C# 4.0. </p>]]></description><category>events</category></item><item><title>What is a number?</title><guid isPermaLink="true">http://timstall.dotnetdevelopersjournal.com/what_is_a_number.htm</guid><link>http://timstall.dotnetdevelopersjournal.com/what_is_a_number.htm</link><pubDate>Wed, 26 Aug 2009 13:52:00 GMT</pubDate><comments>http://timstall.dotnetdevelopersjournal.com/console/comments/popup/?f=what%5Fis%5Fa%5Fnumber</comments><dc:creator>Tim Stall</dc:creator><description><![CDATA[<p>Having an application collect a number from the user seems simple. Just whip out a textbox, maybe add an &quot;integer validator&quot;, and ta da! Sounds great, but endless things can go wrong (things can always go wrong, like with <a href="/the_addresss_state_field_may_contain_more_than_just_the_50_.htm">states</a>, <a href="/how_zip_codes_can_get_complicated.htm">zip codes</a>, or <a href="/what_can_go_wrong_with_changing_a_text_label.htm">even labels</a>). I&#39;m certainly not saying that every textbox in every line of business app should handle all of this, but here are some things to be aware of:</p><ul><li>Do you allow for special characters, like dollar signs &quot;$&quot;, percents &quot;%&quot;, or financial negative numbers &quot;( )&quot;? [Seriously, try formatting a negative dollar amount in Excel]</li><li>Do you allow commas?</li><li>Do you allow decimals?</li><li>Do you handle globalization? Some countries use the &quot;,&quot; for a decimal point, and the &quot;.&quot; for a comma (the inverse of what America does).</li><li>Do you allow both &quot;-&quot; (for negative) and &quot;+&quot; for positive, or is the &quot;+&quot; just implied by default?</li><li>Do you allow pre and post zeros: &quot;001.00&quot;. Keep in mind that the zeros on the left are mathematically redundant, but the zeros on the right may count as &quot;<a href="http://en.wikipedia.org/wiki/Significant_digit">significant digits</a>&quot;, and denote a degree of precision. The extra zeros in &quot;1.25000&quot; implies a much more precise number than just &quot;1.25&quot;. However, most numeric types in .programming languages will truncate the trailing zeros.</li><li>Do you allow exponents for large numbers, like &quot;1E+12&quot; (that&#39;s 1 with 12 zeros after it: &quot;1,000,000,000,000&quot;)?</li><li>Do you allow abbreviations, like &quot;10<strong>M</strong>&quot; for &quot;10,000,000&quot;? (FWIW, I&#39;m not sure of any app that actually does this.)</li><li>Do you have a clearly defined range? For example, a smallint (Int16) stores much smaller numbers than a long (Int64). Most business values can be stored with a double. However, if you&#39;re extending a legacy system that only provides a byte or smallint, but it expects occasionally huge values, then you could get into trouble. </li><li>Is your validation lenient? For example, if the user enters multiple commas &quot;23,5,6&quot; - do you simply remove all the commas and have &quot;2346&quot;, or is that an error?</li><li>How do you handle nulls? Do you use a sentinel value (like Int32.MinValue), or use the new Nullable data types, or something else? If using a nullable value, does it &quot;convert up&quot; - i.e. Int32.MinValue is null if the type if Int32, but it would be a valid non-null value if the type was Int64. If you have multiple systems reading the same value, and one system uses Int32, and the other uses Int64, will your system still work (this can happen when you start doing things like letting the user dynamically create their own pages or reports).</li><li>Not to be smart-alecky about it, but I&#39;d just assume that unless otherwise told, this accepts base-10 inputs. I.e. &quot;A5&quot; and &quot;FF&quot; are invalid values - although there may be apps where that is legit (like specify a color in HTML for some blog or content-management software).</li></ul><p>Also, does your system handle transformations? That&#39;s where you collect the input, store the raw data as something else, and display a newly formatted value. Perhaps the most common example is with percents. A user may type &quot;50&quot; into a textbox (with the &quot;%&quot; in the label next to it), you may save it in the database as &quot;0.5&quot;, and you may format it back as &quot;50%&quot; on a report. Or a user may enter &quot;+0&quot; in a textbox, and you simple store and display it as &quot;0&quot;.</p><p>So, some numerical inputs to test with (besides the obvious invalid numeric inputs, like &quot;xyz&quot;) :</p><ul><li>-23,456.000</li><li>-23.456,00&nbsp;&nbsp;&nbsp; //Globalization</li><li>$45,345.00 </li><li>$(4.00)</li><li>The max/min values for each of the numeric types.</li><li>Fill the entire textbox with 9&#39;s.</li><li>000000000</li><li>+23</li><li>23&nbsp;&nbsp;&nbsp;&nbsp; //try the simple case</li><li>-0</li><li>+0</li><li>1.25E+12</li><li>1.25 E + 12&nbsp;&nbsp;&nbsp; //note the spaces</li></ul><p>The things to look for are (1) will these prompt validation messages, (2) how will each value be stored in the database, and (3) how will the value be re-formatted when it&#39;s displayed. </p><p>Perhaps the best standard is to see how Excel handles it, as Excel is probably the most famous application in the world that handles numbers.</p>]]></description><category>businessrules</category></item></channel></rss>