<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Foo Hack &#187; Freebie</title>
	<atom:link href="http://foohack.com/category/freebie/feed/" rel="self" type="application/rss+xml" />
	<link>http://foohack.com</link>
	<description>Isaac Schlueter on Web Development</description>
	<pubDate>Wed, 06 Jan 2010 01:26:21 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>Programming Puzzles and Our Mismatch Problem</title>
		<link>http://foohack.com/2008/07/programming-puzzles-and-our-mismatch-problem/</link>
		<comments>http://foohack.com/2008/07/programming-puzzles-and-our-mismatch-problem/#comments</comments>
		<pubDate>Mon, 07 Jul 2008 17:00:46 +0000</pubDate>
		<dc:creator>Isaac</dc:creator>
		
		<category><![CDATA[20/20 Hindsight]]></category>

		<category><![CDATA[Freebie]]></category>

		<category><![CDATA[The Business]]></category>

		<guid isPermaLink="false">http://foohack.com/?p=73</guid>
		<description><![CDATA[In interviewing candidates for programming jobs, a common technique is to ask them to solve some programming puzzle.  Makes sense, right?  If the guy&#8217;s smart enough solve random silly questions, he&#8217;s probably good at programming, since that&#8217;s most of what programming is.

As it turns out, this bit of common sense is common bullshit. <small><a href="http://foohack.com/2008/07/programming-puzzles-and-our-mismatch-problem/">...Read More</a></small>]]></description>
			<content:encoded><![CDATA[<p>In interviewing candidates for programming jobs, a common technique is to ask them to solve some programming puzzle.  Makes sense, right?  If the guy&#8217;s smart enough solve random silly questions, he&#8217;s probably good at programming, since that&#8217;s most of what programming is.</p>
<p>As it turns out, this bit of common sense is common bullshit.  It&#8217;s just another <a href="http://www.newyorker.com/online/video/conference/2008/gladwell">mismatch problem</a>, along with requiring elementary school teachers to have lots of formal education, cops to be big and strong, and law school applicants to have great grades in high school.  It doesn&#8217;t predict success <strong>even a little</strong>.</p>
<h3>A Tale of Two Coders</h3>
<p><small>Feel free to <a href="#p73_some_puzzles">skip to the fun stuff</a>.</small></p>
<p>Let me tell you about two programmers I&#8217;ve worked with.</p>
<p>The first graduated from Stanford University in the top 10% of his class with a degree in Computer Science, and went on to get an Master of Science in the subject.  He knew about B+ trees and maps.  He could tell you what a <a href="http://en.wikipedia.org/wiki/Directed_acyclic_graph">directed acyclic graph</a> was, and what it should be used for.  He built an MVC system from scratch to design business cards in a web browser, 2 years <em>before</em> Ajax was &#8220;teh new hotness&#8221;.  He interviewed well, and had a host of companies to choose from.  He chose a job, and was one of the highest paid new hires in the history of the company.</p>
<p>The second graduated from high school, and had absolutely no intentions of ever taking classes again if he could help it.  Not sure what to do with his life, he worked at a local electronics store (Circuit City, I believe) for a few years.  He&#8217;d messed around with computers plenty, programmed a bit, but nothing serious.  A friend of his worked at a software company, and managed to get him a job, despite his lack of experience and education, and despite the fact that he interviewed terribly.  He came in at the low end of the pay scale.</p>
<p>Who was the better programmer?</p>
<p>Since I tipped my hand by talking about the mismatch problem, you&#8217;re probably guessing that the second one was better.  You&#8217;d be right.  But I doubt you&#8217;d realize just HOW right you are.</p>
<p>Despite the fact that I think he deserves any reputation his lack of skill earns him in life, it strikes me as being in poor taste to name him here.  Let&#8217;s call the first programmer &#8220;X&#8221;.</p>
<p>Over a year after X left the company, one of the other guys found that he could reliably predict and fix crazy strange bugs by searching for the guy&#8217;s initials in the codebase.  (There was a fairly strict rule about commenting changes in existing code, which, thankfully, X followed.)  I&#8217;m talking real bone-headed stuff like:</p>
<p><code class="vb block">If Len(".837") = 3 Then</code></p>
<p>When is &#8220;.837&#8243; <strong>ever</strong> 3 characters?!  To make matters worse, that <code class="vb">If</code> block was wrapping about 250 lines of code, some of it <em>essential to our customers getting paid</em>.  X was clearly operating in some kind of alternate universe.  Real <a href="http://thedailywtf.com">DailyWTF</a> type shit.  And, he was the kind of asshat who was nearly impossible to work with.  I mean, imagine any quality that a programmer needs to have, except for IQ, and he lacked it.  He was arrogant, rude, passive aggressive, and lazy.  He was a bully who would go out of his way to make people feel uncomfortable once he decided that he didn&#8217;t like them.  Every design discussion was an Argument from Intimidation&#8212;either you agreed with his idea and stroked his ego, or you were an idiot, plain and simple.  He was good at (useless) puzzles, but his attention to detail in real work was beyond terrible.</p>
<p>Within 2 years at the company, the second guy&#8212;the uneducated, inexperienced, bad interviewer&#8212;was one of the go-to architects who really grokked how everything was supposed to work.  He picked up Visual Basic fast enough to pass by most of the existing team, some of whom had been writing code since he was in high school.  He was responsible for designing and implementing a part of the software that was the primary killer feature.  He redesigned a huge chunk of the program that never quite worked right.  He was in databases, in the presentation layer, and in between.  By any estimation, a very significant portion of the product&#8217;s value was entirely his doing.</p>
<p>After we&#8217;d both left that place, I referred him to Yahoo.  Despite not having very much experience in front-end web development, and again interviewing terribly, the hiring manager was wise enough to heed my very strong recommendation.  And good thing, because he very quickly became one of the most important members of the Yahoo Games team.  (And he occasionally reads this blog and comments on stuff.  Hi, Geoff.)</p>
<p>So, at this point, you might be thinking, <q>Well, if the super educated brainiacs are bad programmers, and the lazy hobbyists are good programmers, then we just need to flip the test around, and use it in reverse.  Then we&#8217;ll find the Geoffs, and avoid the Xes.</q></p>
<p>If only it was that easy.</p>
<p>You see, there actually are quite a few very good programmers that are very good at silly puzzles and have degrees in Computer Science.  Almost every problem has some kind of mathematical component; a lot of the theories were discovered because they&#8217;re true and relevant.  Some of X&#8217;s abilities <em>are</em> quite useful, so having both the will and the skill is best.  The hobbyists eventually find that they have to hit the books and learn theory at some point, or else they get passed by.</p>
<p>But those skills aren&#8217;t nearly <em>as</em> useful or predictive of programming ability as we might think.  Geoff has the attitude of a great hacker and a mind that is capable of learning quickly, which, as it turns out, is much more useful in the long run, and much harder to test for.  X had a big brain and a bad attitude.  <strong>Most of programming is not solving puzzles with algorithms.  Most of programming is communication, attention to detail, and a relentless desire to build something beautiful.</strong></p>
<h3 id="p73_some_puzzles">Some Puzzles</h3>
<p>Despite the fact that programming puzzles are almost 100% useless in the hiring process, they&#8217;re fun, and a good mental work-out to keep your thinking sharp.  They&#8217;re a good part of a practice regimen.  Here are a few that I&#8217;ve come across lately that were pretty interesting.  (Sadly, my beliefs about the foolishness of puzzles-as-hiring-tool are not shared by all of my managers, and I learned about two of these because they are used in our interview process.)</p>
<p>I&#8217;ll edit this post to include solutions later.  I didn&#8217;t make up any of these, but I did revise them somewhat.  The goal in each of them is to devise a program or algorithm that will find a solution in the least number of steps/iterations/whatever.</p>
<h4>Square the Sum</h4>
<p>For all 6-digit numbers from 100000 to 999999, find the numbers that, if you add the top three digits to the bottom three digits, and square the result, it will equal the original number.</p>
<p>For example, for 123456, you&#8217;d add 123 and 456, which equals 579.  Then, square that sum, which yields 579 * 579 = 335241.  335241 ≠ 123456, so 123456 is not in the set.</p>
<h4>Dropping Eggs</h4>
<p>Let&#8217;s say that you have 2 eggs, and a building that is 100 floors tall.  You need to figure out how high up you have to drop the egg to have it break when it hits the pavement.  Assume that the egg either breaks completely or is completely undamaged.  That is, repeatedly dropping from the second floor will not make it more likely to break.  (Hypothetical eggs are very hard, but when they break, they really BREAK.)</p>
<p>For example, if you drop the egg from floor #50 or below, it won&#8217;t break.  But if you drop it from floor #51 or above, it will break.</p>
<p>What is the optimal approach to testing floors?  Assuming that you take that approach, and the egg breaks on the last floor you test, how many times did you have to drop it?</p>
<h5>Part 2</h5>
<p>As the number of floors <em>n</em> increases to a very large number (millions, billions, whatever&#8212;since it&#8217;s really not floors and eggs but a sorted database of records or something), how does your solution scale?</p>
<p>Let&#8217;s say that you have 3 eggs.  What&#8217;s the value now?</p>
<p>As the number of eggs increases, how does the worst-case number of tests change?  If you had an unlimited supply of eggs, is there a better solution?</p>
<p><small>I heard this one at work, and it sounded kind of familiar, but I didn&#8217;t remember the solution right away.  I dug up my textbook from &#8220;CSC212: Data Structures and Algorithm Analysis&#8221;, and sure enough, it was one of the examples Dr. Sayed used to teach us big-O notation.</small></p>
<h4>Non-Repeating Digits (<a href="http://beust.com/weblog/archives/000491.html">Cedric&#8217;s Challenge</a>, slightly revised)</h4>
<p>Find the count of all natural numbers below a certain number of digits that have no repeated digits.  For example, for length=2, the following numbers all satisfy: 10, 12, 21, 23, 32, 34; but these don&#8217;t: 11, 22, 33.  For length=3, 97 and 102 are valid, but 99, 100, and 101 are not.</p>
<p>Additionally, find the two consecutive numbers that are furthest from one another, and the difference between them.  For example, in the length=3 case, the greatest difference between two consecutive numbers is 4, between 98 and 102.</p>
<p>For example, in length=2, there are 90 matches.  (1-99, except for 11,22,33,44,55,66,77,88,99.)  The biggest jump between two consecutive numbers is 2, between 10 and 12.</p>
<h5>Part 2</h5>
<p>In addition to specifying the length in digits, also make the base variable.  For example, in the (base=3,length=3) set, the following numbers are valid: 10, 12, 20, 21, 102, 201.</p>
<p>Compute the values for length=100,base=1000.  Speed matters.</p>
<h5>Part 3 (<a href="http://beust.com/weblog/archives/000491.html">Cedric&#8217;s Challenge</a> + arbitrary bases)</h5>
<p>Print all the numbers in order before printing the count and difference. (Hint: if this doesn&#8217;t make it any more complicated, then you didn&#8217;t do parts 1 and 2 properly.)</p>
<p>Since the base can be arbitrarily high, express numbers in bases greater than 10 as a comma-delimited tuple rather than using character digits, optionally with a trailing comma.  For example, the base-16 number normally written as &#8220;FA9&#8243; could be printed as either &#8220;15,10,9,&#8221; or &#8220;15,10,9&#8243;.</p>
]]></content:encoded>
			<wfw:commentRss>http://foohack.com/2008/07/programming-puzzles-and-our-mismatch-problem/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Hacking the Google Favicon</title>
		<link>http://foohack.com/2008/06/hacking-the-google-favicon/</link>
		<comments>http://foohack.com/2008/06/hacking-the-google-favicon/#comments</comments>
		<pubDate>Sat, 07 Jun 2008 01:36:37 +0000</pubDate>
		<dc:creator>Isaac</dc:creator>
		
		<category><![CDATA[Broken]]></category>

		<category><![CDATA[Freebie]]></category>

		<guid isPermaLink="false">http://foohack.com/?p=68</guid>
		<description><![CDATA[There&#8217;s been a lot of nerd rage about the new google favicon.  I joined in with a rationalization for my distaste for their new design.  After a few days of the lower-case &#8220;g&#8221; on a gray background, I decided today that I just couldn&#8217;t take it.  Here&#8217;s how I fixed it, so <small><a href="http://foohack.com/2008/06/hacking-the-google-favicon/">...Read More</a></small>]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s been a lot of nerd rage about the <a href="http://google.com/favicon.ico">new google favicon</a>.  I joined in with <a href="http://twitter.com/isaacschlueter/statuses/824260982">a rationalization for my distaste</a> for their new design.  After a few days of the lower-case &#8220;g&#8221; on a gray background, I decided today that I just couldn&#8217;t take it.  Here&#8217;s how I fixed it, so my Mac shows the old logo.</p>
<p>Certainly, any company ought to think long and hard about any branding change so fundamental and wide-reaching as a change in logo.  If you&#8217;re a web company, then <strong>your favicon IS your logo, and everything else is secondary</strong>.  For Google&#8217;s sake, I sure hope they understand just how significant this change was, and weighed the pros and cons carefully.</p>
<p>While I recognize my position deep in peanut-gallery territory, I simply cannot accept that it was a good move.  A favicon needs to be:</p>
<ol>
<li><strong>Far from gray.</strong>  Browser tabs are gray, and the purpose of a favicon is to let the faster right-brain processes identify your site in a list of tabs or bookmarks.  If I can&#8217;t see it, it&#8217;s useless.  <strong>FAIL</strong></li>
<li><strong>Mostly not transparent.</strong>  If you&#8217;re going to use a gray logo, fine. Put it on a white background, so you know it will stand out.  A small logo in a transparent background is invisible.  <strong>FAIL</strong></li>
<li><strong>Evoke your corporate branding.</strong>  I should be able to associate your favicon with your brand without thinking about it.  If, for example, your corporate branding is focused on lots of bright colors on a white background, your favicon should echo this.  <strong>FAIL</strong></li>
<li><strong>Use big, simple shapes.</strong>  Fine details (like those in the double-curl style of lower-case &#8220;g&#8221;) get lost at 16&#215;16 size.  <strong>FAIL</strong></li>
</ol>
<p><a href="http://skitch.com/isaacschlueter/pd67/google-favicon" title="favicon: FAIL."><img class="alignleft" src="http://img.skitch.com/20080607-bqcry587c6e63thpawrqxy9qn1.png" alt="Poor contrast.  Not enough pixels.  Not &quot;google&quot; enough.  Prettier - Who cares?  FAIL" width="498" height="412" /></a></p>
<p>Yahoo and Google are effectively equivalent in terms of the objective quality of their search results.  Scores of user-studies have shown that our perception in SERP quality is due primarily to brand loyalty and nothing else.  If you&#8217;re a Yahoo searcher, and you see a red Y, your comfort filter tells you it&#8217;s good, no matter where the results actually came from.  You can&#8217;t tell the difference, because, for the most part, there isn&#8217;t one.  Most of the time, Yahoo and Google search pull up <em>exactly</em> the same sites, or close to it.  They&#8217;re both very very good, and search is a case where there is a right answer, even if the method of finding it is a bit fuzzy.</p>
<p>For some searches, it seems that Yahoo is even significantly better than Google.  <a href="http://twingine.no/">Compare for yourself.</a>  Somewhat humorously, the results for <a href="http://twingine.no/search.php?q=%22yahoo+is+better+than+google%22">&#8220;yahoo is better than google&#8221;</a> seems to yield much better results on Yahoo.  I tried <a href="http://twingine.no/search.php?q=%22google+is+better+than+yahoo%22">the reverse search</a>, expecting to see some kind of amusing self-bias, but actually Yahoo did that better, too.  From my cursory non-scientific view, it seems like Yahoo puts a bit more weight on the title, and there are probably other slight differences.  But the point is, the differences are slight enough to be overlooked.  They&#8217;re both pretty damn good at finding what you ask for.</p>
<p>I work at Yahoo.  But I use Google for search.  I perhaps ought to bleed a little more purple than I do.  I also own stock in Yahoo, so in a small way, using Google for search is not a financially rational move.  So why do I do it?</p>
<p>Brand loyalty.  I was using Google ever since it&#8217;s been around, and I&#8217;ll probably keep using it for a long time.  I imprinted early on that big G in the white square, and some very low-level neural systems tell me loud and proud that, when it comes to searching, that G means Good.  Frankly, rewiring all that stuff isn&#8217;t worth the effort.</p>
<p>I think that brand loyalty explains a lot of the nerd rage over the new favicon.  Yes, it doesn&#8217;t affect the results. Yes, it&#8217;s just a case of <a href="http://en.wikipedia.org/wiki/Who_Moved_My_Cheese">cheese moving</a>, and not even a very relevant one.  And, face it, you&#8217;re not going to stop using Google over it if you&#8217;re already a Google user.  But you may be consistently annoyed for several months while the brain circuits rewire themselves to imprint on the new design.</p>
<p>Unacceptable.  I&#8217;m a web geek.  I&#8217;m a hacker.  There is no way in hell that I should have to put up with something I find even slightly distasteful in my regular internet experience.  I refuse to be subjected to some marketing exec&#8217;s idea of what is best for me, when I clearly know my needs better.  <small>I don&#8217;t even care if he went to Stanford AND coded a rocket ship in Python.</small></p>
<h3 style="color:#900">Warning</h3>
<p>If you use any Google services that require a login (such as GMail, Groups, Orkut, or pretty much anything other than Search), then you&#8217;ll need Apache 2.  I tried really hard to make it work with Apache 1.3, but no dice.</p>
<p>The good news is, Apache 2 comes standard with Leopard.  The bad news is, it <em>doesn&#8217;t</em> come standard with Tiger.</p>
<p>Since I was using Tiger, and Apache 1.3, this was a much more involved hack than I&#8217;d anticipated going in.  Luckily, it&#8217;s just a matter of change one line in the <code>/etc/hosts</code> file to turn it off, which is good, because I had other things to do before I could fix it.  I use <a href="http://www.macports.org/">MacPorts</a> for a bunch of stuff, so I figured I&#8217;d just install Apache 2 that way.</p>
<p>Easier said than done, at least in my case.</p>
<p>I already had PHP and MySQL running a local copy of this site, and some other stuff.  MacPorts really shines if you use it for everything&#8212;try to run Apache on MacPorts and run PHP and MySQL from some other location, and you&#8217;re in for a world of hurt.  It took a lot of SFTW and learning about reconfiguring to get it all working properly.</p>
<p>I&#8217;m not the best guy in the world to critique package management systems, but I&#8217;ve got some end-user experience.  I use apt-get on my web server, MacPorts on my laptop, and of course, yinst on all the Yahoo! machines I work on.  Of course, that&#8217;s not counting the Registry and Add/Remove programs dialog from Windows Land (which is hell), and the much more user-friendly &#8220;Applications&#8221; folder on the Mac (which is lovely, but not really a full-featured package manager).  Of these, yinst is the best, hands down.  Powerful, simple, effective, and sadly, 100% closed-source and proprietary.  If you&#8217;re not at Yahoo, you&#8217;re not using yinst.</p>
<p>But enough about installing stuff.  Long story short, you need Apache 2, or don&#8217;t go any further.  If you primarily use Firefox, you can just follow <a href="http://paulirish.com">Paul</a>&#8217;s <a href="http://foohack.com/2008/06/hacking-the-google-favicon/#comment-672">advice</a>, and <a href="http://userscripts.org/scripts/show/27548">install this Greasemonkey script</a>.</p>
<p>I still recommend doing this, especially if you write code for the web, and you&#8217;re not normally a &#8220;back end guy&#8221;.  It&#8217;s good to tinker with this stuff, and even break it once in a while in your own little sandbox.  Unless you tinker, you never learn anything new.  Newton did revolutionary work in optics, largely motivated by his need for a better telescope to look at the planets.  It&#8217;s good to have a working knowledge of the tools of your trade, even if they&#8217;re just a means to an end.</p>
<p>So, fixing the G favicon&#8230;</p>
<h3>mod_proxy to the rescue!</h3>
<p>The premise of this hack is pretty simple:</p>
<ol>
<li>Edit the <code>/etc/hosts</code> file to point &#8220;www.google.com&#8221; to your local machine.</li>
<li>Use <a href="http://httpd.apache.org/docs/2.0/mod/mod_proxy.html">mod_proxy</a> to transparently send all requests for &#8220;www.google.com&#8221; on to Google&#8217;s actual IP address, except for <code>/favicon.ico</code></li>
<li>Point <code>/favicon.ico</code> at the old favicon file, sitting on your local machine.</li>
</ol>
<p>The interesting thing is that you can do this for <em>any</em> file or url out there that you want to swap in your local machine.  Don&#8217;t like the favicon that a given site uses?  Change it!  You have the power!  That&#8217;s the beauty of the web.</p>
<h3>Prereqs</h3>
<p>For this hack, you&#8217;ll need:</p>
<dl>
<dt>Apache 2 with mod_proxy, mod_ssl, and mod_rewrite</dt>
<dd>
<p>If you have a Mac with Leopard and the developer tools stuff on it, you probably already have this, and might just need to enable them.  I&#8217;ll tell you how.</p>
<p>If you don&#8217;t already have Apache 2 and/or mod_proxy installed, then that&#8217;s outside the scope of this post, like I said above.  Sorry.</p>
</dd>
<dt>About <del>15</del> 30 minutes</dt>
<dd>
<p><del>Yes, it&#8217;s really that easy.</del> It&#8217;s fairly easy, but a bit trickier than I&#8217;d originally thought.</p>
</dd>
</dl>
<p>I use a Mac, and these instructions are fairly mac-centric.  If you use a Linux or Unix machine, then most of it will still make sense.  If you use a Windows machine, then a lot of it won&#8217;t apply, but the basic idea should still be possible if you use Apache and install mod_proxy.</p>
<p>Some Apache setups install the Apache Control script as <code class="bash">apache2ctl</code>, and others call it <code class="bash">apachectl</code>.  Since I used MacPorts, I&#8217;ve got <code class="bash">apachectl</code> on my machine.  Substitute as required for your setup.</p>
<p>If you run into any sticky points you can&#8217;t get out of, post a comment.  I&#8217;d like to hear it.  If you run into any sticky points and DO get out of it, then <em>definitely</em> post a comment!  I&#8217;ll update this post with your info.</p>
<h3>Get the old favicon</h3>
<p>I couldn&#8217;t find the actual ico file, but I found some screenshots on the internet talking about the favicon change.  I got a pretty good png, and lifted out just the 16&#215;16 piece from the address bar in the screenshot.</p>
<p>Then, I used <a href="http://www.winterdrache.de/freeware/png2ico/">png2ico</a> to convert that png to an ico file.  It&#8217;s a great tool that I use all the time to make favicons.  It lets you embed multiple pngs into the ico, but in this case, all that I really care about is the 16&#215;16 that shows up in my address bar and on the tabs in Firefox and Safari.</p>
<p>All in all, that took probably less than 10 minutes.  But you can do this step even faster by just downloading the <a href='http://foohack.com/blog/wp-content/uploads/2008/06/old-google-favicon.tgz'>Old Google Favicon</a>.  Extract it in Terminal or iTerm by doing this:</p>
<p><code class="bash block">tar -xzvf old-google-favicon.tgz</code></p>
<p>You&#8217;ll get a file called <code>old-google-favicon.ico</code>.  Put that under the &#8220;Sites&#8221; folder in your home directory.  If you just un-tarred it using the command above, then it would be:</p>
<p><code class="bash block">mv old-google-favicon.ico ~/Sites/</code></p>
<h3>Turn on Apache</h3>
<p>If you already run web pages and whatnot on your local machine, then you are already set.  Skip to the next step.</p>
<p>To see if Apache is running, fire up a web browser and go to <a href="http://localhost/">localhost</a>.  If you see the default Apache startup screen, then you&#8217;re all set.  If it redirects to <a href="http://localhost.com">localhost.com</a> or a web search, or you get a &#8220;could not connect to server&#8221; message, then you need to enable Apache.</p>
<p>If you&#8217;re running Leopard, open up System Preferences, and click on Sharing.  Click the little lock in the lower-left corner, and enter your password. Check &#8220;Personal Web Sharing&#8221;.</p>
<p>Try hitting <a href="http://localhost/">localhost</a> again.  If it still doesn&#8217;t work, then do this in a terminal:</p>
<p><code class="block bash">sudo apachectl graceful</code></p>
<p>If that doesn&#8217;t work, try:</p>
<p><code class="block bash">sudo apache2ctl graceful</code></p>
<p>If it&#8217;s still not working, sorry, don&#8217;t know what to tell ya.  Good luck.</p>
<h4>Test</h4>
<p>At this point, you should be able to see the desired favicon at <code class="url">http://localhost/~<strong>YOUR_USER_NAME</strong>/old-google-favicon.ico</code>, where YOUR_USER_NAME is the username that you log in with.  (If you&#8217;re not sure what that is, open up a terminal, and type <code class="bash">whoami</code>, and it&#8217;ll tell you.)</p>
<p>If you&#8217;ve configured Apache to have some different document root, then adjust the path accordingly.  For example, since my Mac is effectively a single-user machine, I just have the default document root pointed at <code>/Users/isaacs/Sites/</code>, so the favicon is at <code class="url">http://localhost/old-google-favicon.ico</code>.  Your setup may vary.</p>
<p>Ultimately, it doesn&#8217;t much matter where you put it, since we&#8217;ll be telling Apache exactly where to find it later.</p>
<h3>Enable Apache Modules</h3>
<p>Fire up your favorite text editor, and open your <code>httpd.conf</code>.  By default, this file is in <code>/etc/httpd/</code> or <code>/etc/apache2/</code>; if you installed with MacPorts, then it&#8217;s in <code>/opt/local/etc/apache2/</code>.  (You&#8217;ll have to save it as the super-user, since it&#8217;s a root-owned file, so that means vi and emacs users will have to open it with <code>sudo</code>.  GUI editors will usually prompt for your password when you try to save the file.)</p>
<p>Each of these lines have to be in there somewhere.  If they&#8217;re missing, add them.  If they&#8217;re commented-out, un-comment them.</p>
<p><code class="block apache">LoadModule proxy_module modules/mod_proxy.so<br />
LoadModule proxy_connect_module modules/mod_proxy_connect.so<br />
LoadModule proxy_http_module modules/mod_proxy_http.so<br />
LoadModule ssl_module modules/mod_ssl.so<br />
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so<br />
LoadModule rewrite_module modules/mod_rewrite.so</code></p>
<p>If you notice that these rules look &#8220;out of place&#8221; for the stuff that&#8217;s already there, then modify to match.  For example, if the other rules are all loading the .so files out of &#8220;libexec&#8221;, then change &#8220;modules&#8221; to &#8220;libexec&#8221;.</p>
<p>Restart apache by running this command in a terminal:</p>
<p><code class="block bash">sudo apachectl graceful</code></p>
<p>If it tells you that the server couldn&#8217;t be restarted, try this to get a more helpful error message:</p>
<p><code class="block bash">sudo apachectl configtest</code></p>
<p>If it&#8217;s not working, sorry, don&#8217;t know what to tell ya.  You may need to install some of the required modules using the apxs utility.</p>
<h3>SSL</h3>
<p>Because we&#8217;ll be proxying an SSL (ie, https://&#8230;) connection, your server will have to be able to do SSL so that it can maintain the level of encryption.</p>
<p>I followed <a target="_new" href="http://developer.apple.com/internet/serverside/modssl.html" title="Using mod_ssl on Mac OS X" rev="vote-for">these instructions</a> to create SSL keys.  It directs you towards a <code>sign.sh</code> script, and finding that was a bit tricky.  For your convenience, I&#8217;ve <a href="http://foohack.com/blog/wp-content/uploads/2008/06/sign.sh">provided it here</a>.</p>
<p>Also, I put the <code>ssl.key</code> folder in the same folder as the other Apache stuff, the location of the <code class="apache">ServerRoot</code> directive.  That way, I can refer to it by a relative path.  If you prefer to have it in a separate location, that&#8217;s fine, but you&#8217;ll need to refer to it by the complete path in the configs below.</p>
<h3>Get Google&#8217;s IP Addresses</h3>
<p>In a terminal, run this:</p>
<p><code class="bash block">nslookup www.google.com</code></p>
<p>You&#8217;re looking for the &#8220;Address&#8221; lines, not the &#8220;Server&#8221; line.  In <a href="/tests/bash_extras">my bash profile</a>, I have a handy shortcut for this, so I just type <code class="bash">getip www.google.com</code> to see the results from both nslookup and ping.</p>
<p>Make a note of those IP addresses.  As of this writing, from my location, I got these:</p>
<p><code class="block">66.249.89.104<br />
66.249.89.147<br />
66.249.89.99</code></p>
<p>We&#8217;re actually going to define a load balancer to distribute your requests between these three.  While that&#8217;s probably overkill, part of the benefit of this is educational, and that&#8217;s what a proxy would normally do.</p>
<h3>Host File</h3>
<p>Open up your <code>/etc/hosts</code> file in a text editor, and add this line:</p>
<p><code class="block hosts">127.0.0.1 www.google.com</code></p>
<p>Then, in a terminal, run this command to refresh your IP caches:</p>
<p><code class="block bash">lookupd -flushcache</code></p>
<p>Bring up <a href="http://www.google.com">www.google.com</a> in a web browser, and you should be looking at that default Apache page again.  If so, you&#8217;re on track.  If not, figure out what went wrong.  You can see if Apache is in trouble by running this command and then hitting the url again:</p>
<p><code class="bash block">tail -f /var/log/apache2/error_log</code></p>
<p>MacPorts users: <code class="bash">tail -f /opt/local/apache2/logs/error_log</code></p>
<p>You may need to comment that line out with a # and do the <code class="bash">lookupd -flushcache</code> if you want to search google while doing this.  Or you could just use <a href="http://ysearch.com">Yahoo! Search</a> temporarily.  Maybe in the process, you&#8217;ll get used to Yahoo search and even find that you like it better.  (See?  I&#8217;m a good little purple-blooded corporate monkey!)</p>
<h3>Set up mod_proxy</h3>
<p>So, now let&#8217;s take your new and un-improved www.google.com, and turn it into a proxy for the actual www.google.com.</p>
<p>If you have a separate conf file where you keep your Apache customizations (which I highly recommend), then add this stuff in there.  If you don&#8217;t, then you can just add it to <code>/etc/httpd/httpd.conf</code> or <code>/etc/apache2/httpd.conf</code> or <code>/opt/local/apache2/conf/httpd.conf</code>.  Either way should work, as long as Apache finds out about it somehow.</p>
<p>Stuff that you may need to change wrapped in <strong>strong tags</strong>.</p>
<p><code class="block apache">#google proxy stuff<br />
Listen 443<br />
SSLPassPhraseDialog builtin<br />
SSLSessionCache dbm:/var/run/ssl_scache<br />
SSLMutex file:/var/run/ssl_mutex<br />
SSLRandomSeed startup builtin<br />
&lt;VirtualHost *:80&gt;<br />
	# the place where you put the .ico file.<br />
	DocumentRoot <strong>/Users/isaacs/Sites/</strong><br />
	ProxyPreserveHost On<br />
	ProxyRequests Off<br />
	ServerName www.google.com<br />
	&lt;LocationMatch .*&gt;<br />
		Order deny,allow<br />
		Allow from 127.0.0.1<br />
	&lt;/LocationMatch&gt;<br />
	SSLProtocol all -SSLv2<br />
	SSLSessionCacheTimeout 300<br />
	AllowCONNECT 443 563 80<br />
	SSLEngine on<br />
	# enable SSLv3 but not SSLv2<br />
	SSLProtocol all -SSLv2<br />
	SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL<br />
	SSLCertificateFile <strong>ssl.key/server.crt</strong><br />
	SSLCertificateKeyFile <strong>ssl.key/server.key</strong><br />
	# correction for browsers that don&#8217;t always handle SSL connections well<br />
	# You don&#8217;t really use MSIE on your own machine, though, do you??<br />
	SetEnvIf User-Agent &#8220;.*MSIE.*&#8221; \<br />
		nokeepalive ssl-unclean-shutdown \<br />
		downgrade-1.0 force-response-1.0<br />
	SSLProxyEngine on<br />
	&lt;Proxy balancer://googlecluster&gt;<br />
		# the IP addresses you fetched before.<br />
		BalancerMember http://<strong>66.249.89.104</strong><br />
		BalancerMember http://<strong>66.249.89.147</strong><br />
		BalancerMember http://<strong>66.249.89.99</strong><br />
	&lt;/Proxy&gt;<br />
	# Browsing History seemed broken unless it proxies back to https.<br />
	# This is probably safer anyhow, for privacy.<br />
	ProxyPass /history https://www.google.com/history<br />
	ProxyPassReverse /history https://www.google.com/history<br />
	RewriteEngine On<br />
	RewriteRule /favicon.ico /old-google-favicon.ico [L]<br />
	ProxyPass / balancer://googlecluster/<br />
&lt;/VirtualHost&gt;<br />
&lt;VirtualHost *:443&gt;<br />
	# the place where you put the .ico file.<br />
	DocumentRoot <strong>/Users/isaacs/Sites/</strong><br />
	ProxyPreserveHost On<br />
	ProxyRequests Off<br />
	ServerName www.google.com<br />
	&lt;LocationMatch .*&gt;<br />
		Order deny,allow<br />
		Allow from 127.0.0.1<br />
	&lt;/LocationMatch&gt;<br />
	&lt;Proxy balancer://googlecluster&gt;<br />
		# the IP addresses you fetched before.<br />
		# note the &#8220;http<strong>s</strong>&#8221; on these ones.<br />
		BalancerMember https://<strong>66.249.89.104</strong><br />
		BalancerMember https://<strong>66.249.89.147</strong><br />
		BalancerMember https://<strong>66.249.89.99</strong><br />
	&lt;/Proxy&gt;<br />
	SSLProtocol all -SSLv2<br />
	SSLSessionCacheTimeout 300<br />
	AllowCONNECT 443 563 80<br />
	SSLEngine on<br />
	# enable SSLv3 but not SSLv2<br />
	SSLProtocol all -SSLv2<br />
	SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL<br />
	SSLCertificateFile <strong>ssl.key/server.crt</strong><br />
	SSLCertificateKeyFile <strong>ssl.key/server.key</strong><br />
	# correction for browsers that don&#8217;t always handle SSL connections well<br />
	# You don&#8217;t really use MSIE on your own machine, though, do you??<br />
	SetEnvIf User-Agent &#8220;.*MSIE.*&#8221; \<br />
		nokeepalive ssl-unclean-shutdown \<br />
		downgrade-1.0 force-response-1.0<br />
	SSLProxyEngine on<br />
	RewriteEngine On<br />
	RewriteRule /favicon.ico /old-google-favicon.ico [L]<br />
	ProxyPass / balancer://googlecluster/<br />
&lt;/VirtualHost&gt;</code></p>
<p>Save the file, and then restart Apache:</p>
<p><code class="block bash">sudo apachectl graceful</code></p>
<p>Again, if it doesn&#8217;t work, try this to figure out what&#8217;s wrong:</p>
<p><code class="block bash">sudo apachectl configtest</code></p>
<h4>Test</h4>
<p>Now, go to <a href="http://www.google.com">www.google.com</a>.  You should see the google home page, complete with the old lovable [G] favicon.  If you see google, but not the old favicon, go <a href="http://www.google.com/favicon.ico">directly to the favicon.ico</a> and refresh a whole bunch.  Clear your cache, etc.</p>
<p>If you get the new favicon, try running some tests.  Search, go to <a href="https://www.google.com/account/ManageAccounts">your account</a>.  Make sure everything works.</p>
<p>When you hit an https address, you&#8217;ll get a prompt that the certificate is issued by an untrusted authority.  This is good!  Check the cert details, and make sure that they&#8217;re what you typed when you created the certificate.  Now, the question, do you trust yourself?  (I&#8217;d already added myself as a trusted authority, so didn&#8217;t get this problem in Firefox, but I did see it in Safari.)</p>
<p>If it doesn&#8217;t show you the new favicon, then you might have put the virtual host config someplace where it doesn&#8217;t belong, or where it won&#8217;t be picked up.  Tail the error_log file and see if Apache tells you anything is wrong.  Note that some Apache configurations use &#8220;apache.conf&#8221; instead of &#8220;httpd.conf&#8221;, so maybe try that.</p>
<p>If it doesn&#8217;t load at all, tail the apache logs again, and see if anything is barfing.</p>
<h3>Done</h3>
<p>You may now resume your google usage as normal, before the disruptive new favicon appeared.</p>
<p>Note: The Google Notifier won&#8217;t work, because it checks the certificate, and doesn&#8217;t give you the option to trust another authority, which is, in my opinion, very bad design.  Also, the Google Notifier sends your password and username out in clear text by default, so it&#8217;s very insecure.  You shouldn&#8217;t be using it in the first place.</p>
<p>Instead, you can use the <a href="https://mail.google.com/mail/feed/atom">RSS feed</a> to get inbox alerts without exposing your info.</p>
]]></content:encoded>
			<wfw:commentRss>http://foohack.com/2008/06/hacking-the-google-favicon/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Steal My Bash Profile</title>
		<link>http://foohack.com/2008/05/steal-my-bash-profile/</link>
		<comments>http://foohack.com/2008/05/steal-my-bash-profile/#comments</comments>
		<pubDate>Wed, 07 May 2008 03:32:22 +0000</pubDate>
		<dc:creator>Isaac</dc:creator>
		
		<category><![CDATA[Freebie]]></category>

		<category><![CDATA[Tools of the Trade]]></category>

		<guid isPermaLink="false">http://foohack.com/?p=66</guid>
		<description><![CDATA[Feel free to skip the monologue and just get the goodies.

I am in love with the Bourne Again Shell.  Bash is a fantastic terminal environment, and a very interesting programming language in its own right.

I grew up using DOS.  Unix shells always seemed scary and foreign, for some reason.  I think a <small><a href="http://foohack.com/2008/05/steal-my-bash-profile/">...Read More</a></small>]]></description>
			<content:encoded><![CDATA[<p><small>Feel free to skip the monologue and just <a href="http://github.com/isaacs/dotfiles/tree/master">get the goodies</a>.</small></p>
<p>I am in love with the <a rev="vote-for" href="http://www.gnu.org/software/bash/manual/bashref.html">Bourne Again Shell</a>.  Bash is a fantastic terminal environment, and a very interesting programming language in its own right.</p>
<p>I grew up using DOS.  Unix shells always seemed scary and foreign, for some reason.  I think a big part of the reason that I stayed on Windows for as long as I did was that I knew DOS, and could always resort to it in times of need.  As a support tech in college, I got very familiar with DOS.  It was comfortable and handy.</p>
<p>When I got into web programming, I had no choice but to learn at least the rudimentary basics of a unix-style environment.  At that time, I was as a support tech at a software company whose product uses VisualBasic ASP over IIS, and had started playing around in that environment.  However, I had no money, and web hosts that support ASP cost money.</p>
<p>By some stroke of luck or persistence, I managed to find a host that was free, <a href="http://beigetower.org">Beigetower</a>. <small>That link doesn&#8217;t work any more, of course.  I don&#8217;t know how long that server&#8217;s been down.  Cuong Nghiem&#8217;s still listed as the owner on whois, though.)</small>  On top of that, they provided shell access.  Not being able to resist the temptation to tinker with a real live web server, I learned enough Bash to poke around.  As I learned more PHP, I picked up more bits and pieces along the way.</p>
<p>When I started at Yahoo, it was sink or swim to some extent.  I was issued a FreeBSD dev box, and a windows desktop.  I did most of my development in my safe windows world, but there are *a lot* of things you have to do on your dev box as an engineer at Yahoo that simply can&#8217;t be done in any other way.  Bash was a regular part of my daily routine almost from the first day.</p>
<p>Eventually, I fell so head over heels in love with Bash that I had to say goodbye to Windows and get a Mac.</p>
<p>There are many good reasons to get a Mac instead of a PC. They&#8217;re easier and more intuitive in a lot of ways.  They certainly look a lot nicer on almost every level.  But I&#8217;d be lying if I said that having Bash right there all the time wasn&#8217;t the ultimate dealmaker.</p>
<p>One of the best things about Bash, in my opinion, is the fact that you can add shortcuts to your <code>.profile</code> (or <code>.bash_profile</code> or <code>.bashrc</code>, of course) that will be loaded every time you log in.  As soon as I learned this, I started adding stuff.</p>
<p>Eventually, I had my profile so tricked out that it was hideously painful to have to work on a machine that didn&#8217;t have my shortcuts.  Without my customized prompt, I&#8217;d get really confused about which directory I was currently in, and have to type <code>pwd</code> every three seconds just to not get lost.  The sequence would usually go like this:</p>
<p><code class="block">$ la<br />
-bash: la: command not found<br />
$ la<br />
-bash: la: command not found<br />
$ la<br />
-bash: la: command not found<br />
$ alias la="ls -laF"</code></p>
<p>Those first few entries of <code>la</code> were accompanied by plenty of growling and confusion, <em>every. single. time.</em></p>
<p>So, I got into the habit of using <code>scp</code> or <code>rsync</code> to send my bash profile to any machine that I&#8217;d have to work on.  However, some machines have <code>vi</code>, and some don&#8217;t.  I&#8217;d make a change on the profile on my mac, and forget to sync it to my dev box.  Machines that I didn&#8217;t log into often would be so far out of date that it was the &#8220;la&#8221; situation all over again.  What&#8217;s worse, I put some stuff in other shell script files that were called by the profile to do other things, so it was no longer straightforward to keep them in sync.  I&#8217;d send half the package, and then log in, and be inundated with errors all over the place.</p>
<p>When I switched from FreeBSD to a Red Hat Linux box, half my stuff didn&#8217;t work quite the same way.  Also, I moved Foo Hack to a great <a rev="vote-for" href="http://www.slicehost.com/">new host</a>, which is running Ubuntu.  On the Mac, I use <a href="http://macports.org">MacPorts</a>, and the Ubuntu slice uses <a href="http://www.debian.org/doc/manuals/apt-howto/">apt-get</a>, and the RHEL of course uses yinst, the Yahoo! package management tool that quite simply makes all others look like crap by comparison.  (Sadly, yinst is not open source.  There&#8217;s <a href="http://svn.marc.abramowitz.info/projects/hacks/yinst">this hack</a> to simulate yinst on top of apt, though.)  The Ubuntu and RHEL environments used vi as the default editor, but I&#8217;d changed that on the Mac to point to <code>mate</code>, the command-line interface to <a href="http://macromates.com">TextMate</a>.</p>
<p>To say the least, a simple sync wasn&#8217;t cutting it even a little.</p>
<p>I re-wrote all my bash profile goodies to fit in a single file.  Shell scripts were replaced with functions so that they could all live together.  The <code>edit</code> command was defined to use the first available editor from a list of alternatives.  Then, I put it in a file that was external from the main <code>.profile</code> or <code>.bashrc</code> file, so that it could be synced without overwriting anything that the OS placed in there by default.  The only thing to do on a new server was to add <code>. ~/.extra.bashrc</code> to the bottom of whatever profile script it was already using.</p>
<p>I had already added a command called <code>editprof</code> that would bring my profile up in an editor.  All that was needed then was a <code>pushprof</code> command that would rsync the .extra.bashrc file to a given host.</p>
<p>I&#8217;m releasing it under the <a href="http://sam.zoy.org/wtfpl/">WTFPL</a>.  There are actually a few files, since some stuff simply didn&#8217;t make any sense to have in certain environments.  The copy <del>here on foohack.com</del> <ins>on github</ins> is <del>symlinked from my home directory</del> <ins>updated frequently</ins>, so it&#8217;ll stay pretty up to date.  Feel free to copy, learn, fork, or, like the license says, just do <abbr title="what the fuck">wtf</abbr> you like with it.</p>
<p>A word of warning: like government regulation, this file increases in size but rarely gets revised.  Some stuff may be completely useless or pointless.  Some of it I hardly ever use any more.  Figuring out better solutions to these problems is left as an exercise for the reader.</p>
<p><a href="http://github.com/isaacs/dotfiles/tree/master">Get my bash extras.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://foohack.com/2008/05/steal-my-bash-profile/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Open in TextMate in Finder for Tiger</title>
		<link>http://foohack.com/2008/04/open-in-textmate-in-finder-for-tiger/</link>
		<comments>http://foohack.com/2008/04/open-in-textmate-in-finder-for-tiger/#comments</comments>
		<pubDate>Wed, 09 Apr 2008 09:03:49 +0000</pubDate>
		<dc:creator>Isaac</dc:creator>
		
		<category><![CDATA[Freebie]]></category>

		<guid isPermaLink="false">http://foohack.com/?p=64</guid>
		<description><![CDATA[This post has a great little droplet that can be added to the Finder toolbar to open either the selected items or the current Finder folder in TextMate.

Sadly, it doesn&#8217;t work in Tiger, and I haven&#8217;t made the jump to Leopard yet.  If you&#8217;re a TextMate user who&#8217;s still on Tiger, and wants this <small><a href="http://foohack.com/2008/04/open-in-textmate-in-finder-for-tiger/">...Read More</a></small>]]></description>
			<content:encoded><![CDATA[<p><a href="http://henrik.nyh.se/2007/10/open-in-textmate-from-leopard-finder">This post</a> has a great little droplet that can be added to the Finder toolbar to open either the selected items or the current Finder folder in TextMate.</p>
<p>Sadly, it doesn&#8217;t work in Tiger, and I haven&#8217;t made the jump to Leopard yet.  If you&#8217;re a TextMate user who&#8217;s still on Tiger, and wants this feature, I tweaked Henrik&#8217;s AppleScript to play nice with Tiger.</p>
<p><a href='http://foohack.com/blog/wp-content/uploads/2008/04/open-in-textmate-tiger.dmg'>Open in TextMate (for Tiger)</a></p>
<p>Enjoy!</p>
<p><ins datetime="2008-05-04T06:50:12+00:00"><strong>Update</strong>: Just fixed the script to work with folders and files that have spaces in the name.</ins></p>
]]></content:encoded>
			<wfw:commentRss>http://foohack.com/2008/04/open-in-textmate-in-finder-for-tiger/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.377 seconds -->
