<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Pervasive Code</title>
	<atom:link href="http://www.pervasivecode.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pervasivecode.com/blog</link>
	<description>Jamie Flournoy's Software Development Blog</description>
	<lastBuildDate>Fri, 09 Mar 2012 19:27:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Tips for Programmer Interviews at Large Tech Companies</title>
		<link>http://www.pervasivecode.com/blog/2012/03/09/tips-for-interviewing-at-large-tech-companies/</link>
		<comments>http://www.pervasivecode.com/blog/2012/03/09/tips-for-interviewing-at-large-tech-companies/#comments</comments>
		<pubDate>Fri, 09 Mar 2012 19:25:35 +0000</pubDate>
		<dc:creator>jamieadmin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=273</guid>
		<description><![CDATA[Interviewing at large tech companies is different from interviewing at a startup. Here are some tips about how the interview process differs, and some specific advice for how you can prepare.

Programmers who have spent a lot of time reading startup-focused blogs and news sites may have come to expect verbal phone screens and interviews followed [...]]]></description>
			<content:encoded><![CDATA[<p>Interviewing at large tech companies is different from interviewing at a startup. Here are some tips about how the interview process differs, and some specific advice for how you can prepare.<br />
<span id="more-273"></span><br />
Programmers who have spent a lot of time reading startup-focused blogs and news sites may have come to expect verbal phone screens and interviews followed by a trivial coding exercise (&#8220;reverse this string&#8221;) and maybe a probationary hiring period, because that&#8217;s what makes sense for small companies. Startups don&#8217;t get that many candidates in the door, and can afford to hire someone as a contractor based on a good feeling and terminate them if they don&#8217;t work out. Also, startups generally want to hire someone yesterday and need that person to &#8220;hit the ground running&#8221;, meaning that they need that person to start contributing immediately.</p>
<p>Large, well-known tech companies have a different problem. They have a huge number of candidates applying for each position, and they really want to hire extremely smart people who will make tremendous contributions over time, allowing for top notch graduates who don&#8217;t necessarily have a lot of experience with particular technologies, while keeping out candidates who are not really good at programming. Large companies are also litigation targets, so firing someone is not as easy. As a result of that, hiring someone is not as easy to do.</p>
<p>This difference shows up in the way that large tech companies interview candidates. The classic puzzle questions (made famous by Microsoft, and imitated by many since then) are designed to measure intelligence via problem solving ability. Whether they ever accomplished that is debatable, but this sort of interviewing is now easy to prepare for because there are so many answer guides available online.</p>
<p>A more respected technique of interviewing programmers that has survived is the coding interview. In my career I have found that most of the companies that required me to code in an interview were better overall (nicer companies to work for, more successful, with smarter co-workers) so I am happy when a company I&#8217;m interviewing for asks me to write some code.</p>
<p>However, in my experience as an interviewer at several companies, programming job candidates are generally unprepared for this type of interview. I suspect that this is because they expect to just have to answer questions verbally and then get hired, proving their skills afterward. As I mentioned above, this may make sense for startup companies due to the lower volume of candidates, but for large tech companies, this is not feasible. (Similarly, for smaller companies growing quickly, such as a startup that just got a VC cash infusion that is ready to staff up, hiring a bunch of promising candidates and then having your existing programmers look over their shoulder for the first few weeks may not be feasible due to the sheer number of people they&#8217;d have to keep an eye on.)</p>
<p>When I was a college freshman studying electrical engineering, I was shocked at the workload in the engineering classes that every engineer had to take, as compared to some of the general prerequisite classes or more specific EE courses. I later learned the term &#8220;weed-out course&#8221;, which refers to a course designed to both teach the material and to &#8220;weed out&#8221; (eliminate) students who were not prepared to work hard and really pursue that major.</p>
<p>Larger companies need to use coding exercises in interviews as a &#8220;weed-out&#8221; technique, to eliminate the weak candidates as early as possible. So if you&#8217;re trying to get hired at a large tech company, you need to get over the idea that you can talk your way into a job, and prepare yourself for the somewhat unnatural challenge of coding during an interview.</p>
<p><strong>Coding Interview Advice</strong></p>
<p>Working on a small, unfamiliar problem with no language reference, no API reference, no autocomplete, and no error highlighting really flusters some people. This is a hurdle that you will have to overcome in order to demonstrate that you are in fact a good programmer.</p>
<p>Specifically, you should develop the ability to write a correct 10-20 line program body on a whiteboard, a piece of paper, napkin, etc. under time pressure in your preferred language. Practicing in ink on paper, maybe using a sharpie or dry-erase marker on a legal pad, and then typing it in and trying to compile and run it, is great practice. </p>
<p>Also, as a programmer your job is to talk to people and understand the problem that your code is supposed to solve. This is incredibly important in real programming work, and is a gigantic topic in itself (e.g. are the requirements you&#8217;re being given really the requirements or are they someone else&#8217;s partial solution to the real problem, which you can negotiate?). Not surprisingly, if you solve the wrong problem in your interview, you won&#8217;t give a good impression even if your code solves some other problem that the interviewer doesn&#8217;t care about.</p>
<p>So, make sure that you fully understand the problem; repeating it back to the interviewer and maybe rephrasing it is a great way to do this. Write down lots of notes and scribbles (tables, diagrams, maybe the exact text of the question as the interviewer said it) until you completely understand the algorithm and corner cases before jumping to code. The last thing you should do is to write out the code, and it should be obvious to you and the interviewer that you already have solved the problem before you do so. Remember how your math teachers insisted that you show your work instead of just writing down the answer? This is a good way to think about coding interviews: you need to show how you got from the question to a particular solution; this will help you avoid misunderstanding the question, gives the interviewer a chance to correct any confusion you have about what the problem is, and will force you to really think through your solution. You don&#8217;t want to be distracted by looking around the room for an eraser or trying to improve the penmanship of your curly braces while you scribble some half-baked code on the whiteboard and then constantly erase and rewrite it as you think. Finish thinking through your solution in detail, then write down the code.</p>
<p>Finally, practice with friends in mock coding interviews.  If you&#8217;re lucky you will have other programmer friends who can benefit from switching places and letting you be the interviewer, and you may be able to learn how to be a better interviewee from watching them make mistakes. :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2012/03/09/tips-for-interviewing-at-large-tech-companies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Patch to make Ubuntu&#8217;s GNU Screen bash completion work better</title>
		<link>http://www.pervasivecode.com/blog/2012/02/01/patch-to-make-ubuntus-gnu-screen-bash-completion-work-better/</link>
		<comments>http://www.pervasivecode.com/blog/2012/02/01/patch-to-make-ubuntus-gnu-screen-bash-completion-work-better/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 06:11:00 +0000</pubDate>
		<dc:creator>jamieadmin</dc:creator>
				<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=258</guid>
		<description><![CDATA[If you make a screen with a name using screen -S foo and then try and reattach later using screen -R f&#60;tab&#62; it doesn&#8217;t work. It only completes the full name as seen in screen -ls which starts with the PID of the detached screen, like 9972.foo. Not very convenient. Why can&#8217;t it just complete [...]]]></description>
			<content:encoded><![CDATA[<p>If you make a screen with a name using <code>screen -S foo</code> and then try and reattach later using <code>screen -R f&lt;tab&gt;</code> it doesn&#8217;t work. It only completes the full name as seen in <code>screen -ls</code> which starts with the PID of the detached screen, like <code>9972.foo</code>. Not very convenient. Why can&#8217;t it just complete using the name you gave it?</p>
<p><a href="http://alioth.debian.org/tracker/?func=detail&#038;atid=413095&#038;aid=311540&#038;group_id=100114">Someone else solved this problem three years ago</a> but nobody accepted their patch, and now /etc/bash_completion.d/screen has been overhauled and the patch no longer applies.</p>
<p>I updated the patch so it works and <a href="https://bugs.launchpad.net/ubuntu/+source/bash-completion/+bug/924676">resubmitted it to Ubuntu</a>.</p>
<p>If you don&#8217;t wanna wait, grab the code from <a href="https://gist.github.com/1715383">this gist</a> and do this:</p>
<pre>sudo patch /etc/bash_completion.d/screen screen.patch</pre>
<p>This will probably work on Debian too since that&#8217;s where the completion script came from.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2012/02/01/patch-to-make-ubuntus-gnu-screen-bash-completion-work-better/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On Ruby&#8217;s Expressiveness- The Littlest Microframework Explained</title>
		<link>http://www.pervasivecode.com/blog/2011/03/27/on-rubys-expressiveness-the-littlest-microframework-explained/</link>
		<comments>http://www.pervasivecode.com/blog/2011/03/27/on-rubys-expressiveness-the-littlest-microframework-explained/#comments</comments>
		<pubDate>Sun, 27 Mar 2011 20:14:26 +0000</pubDate>
		<dc:creator>jamieadmin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=250</guid>
		<description><![CDATA[In the past few weeks, I&#8217;ve had a few conversations with web developers and back-end engineers who are unfamiliar with Ruby, in which I&#8217;ve tried to explain how Ruby can be nearly as expressive as Perl (tiny amounts of code can accomplish a lot) while being as readable as Python or Java. In fact, I [...]]]></description>
			<content:encoded><![CDATA[<p>In the past few weeks, I&#8217;ve had a few conversations with web developers and back-end engineers who are unfamiliar with Ruby, in which I&#8217;ve tried to explain how Ruby can be nearly as expressive as Perl (tiny amounts of code can accomplish a lot) while being as readable as Python or Java. In fact, I think that Ruby&#8217;s expressiveness can remove distracting boilerplate code, allowing compact expressions to be far more readable than a more verbosely written version of the same algorithm.<br />
<span id="more-250"></span><br />
Sadly, if you are not a Ruby developer, this may sound rather suspicious &mdash; what is this, cult gibberish? &#8220;As expressive as Perl without being hard to read? Nonsense! The only way to make readable code is to use Java, and to write 5x as many lines as is absolutely necessary, embedding a comment before every line and a Javadoc with as many lines of explanation as the code in the method.&#8221; I disagree; I think code should be self-documenting, and that it should be clear <i>to a programmer familiar with that language</i> what the code is doing, without the need for inline comments except in rare cases.</p>
<p>Well, a few months ago <a href="http://www.igvita.com/">Ilya Grigorik</a> posted <a href="https://gist.github.com/675667">a Gist containing a really amusing microframework</a> that is one of the most brilliantly expressive bits of code I&#8217;ve ever seen, without being particularly hard to read. 13 lines of Ruby code provides a web application that will allow any Ruby object you choose to have its entire public API exposed via URLs of the form /method/arg1/arg2, where the method return value becomes the response body.</p>
<p>For the benefit of non-Ruby developers, I&#8217;m going to walk through all 13 lines of code plus the 1-line example application to explain how it works. I really hope that by reading through this explanation you will come to appreciate the expressiveness of Ruby, and maybe what a clever bit of dynamic language programming this is.</p>
<p>Here is the code: <a href="https://gist.github.com/675667">Inspired by @JEG2&#8217;s talk at Rubyconf&#8230; Any ruby object, as a webapp! &#8216;Cause we can. :-)</a><br />
In particular, note the 7th comment, with the embedded animated GIF. This should put you into the right frame of mind for understanding this code.</p>
<p>Line 1: Load <a href="http://rubygems.org/">RubyGems</a>, which is a library that helps you manage other Ruby libraries that your code depends on.</p>
<p>Line 2: Load <a href="http://rack.rubyforge.org/">Rack</a>, which is a standard API for connecting web servers to web application frameworks.</p>
<p>Line 4: We are modifying the Object class itself, so our changes will affect every object in the application.</p>
<p>Line 5: We are adding an instance method called &#8220;webapp&#8221; to every object.</p>
<p>Line 6: We are going to modify the class of just the instance whose &#8220;webapp&#8221; method was invoked. This may seem paradoxical: how can you modify its class without affecting all other instances of that class? The answer is that we are actually creating a unique, anonymous subclass, and the object whose &#8220;webapp&#8221; method was invoked now  becomes an instance of it. So when a caller invokes &#8220;webapp&#8221; on an object, we will modify just that instance.</p>
<p>Line 7: We are defining a method in our anonymous subclass named &#8220;call&#8221;, which takes a single argument, &#8220;env&#8221;. This is what the Rack API will invoke to ask our web application to handle each web server request.</p>
<p>Line 8: We are splitting the URL path on occurrences of &#8220;/&#8221; and storing the result into an array, and then filtering out all elements of that array that return true when the &#8220;empty?&#8221; method is called on them. Then, using multiple assignment, we take the first element of the array and assign it to the local variable &#8220;func&#8221;, and a new array containing the remaining elements to the local variable &#8220;attrs&#8221;.</p>
<p>Line 9: The Rack API expects a return value of an array containing 3 elements: an HTTP status code, a hash of HTTP response header names and values, and the response body. So here we respond with that array. &#8220;send(func, *attrs)&#8221; is an expression that calls &#8220;send&#8221; on self, which lets you invoke a method without specifying the name of the method nor the arguments to be passed to it until runtime. The method invoked is the one named in func, and the argument list passed to that method are taken from the attrs array. This is how the URL of the web request is mapped onto the API of the object that you made into a webapp.</p>
<p>Line 12: The return value from invoking the &#8220;webapp&#8221; method will be the same object that &#8220;webapp&#8221; was invoked on, which now has our special &#8220;call&#8221; method added.</p>
<p>Okay, so that&#8217;s it: a tiny Ruby web app microframework. Now we&#8217;re going to use it to expose an object!</p>
<p>Line 16: Start up the Mongrel web server listening on port 9292, and load up an empty array as a Rack webapp.</p>
<p>Lines 17-19 are a joke: because our webapp is an array, we have just implemented a horizontally scalable in-memory sharded NoSQL database, which is really the only suitable option for our expected ROFLScale needs.</p>
<p>Line 23: [].push(1) returns [1]; rack calls .to_s (convert to string) which returns &#8220;1&#8243; as the response body.<br />
Lines 24 and 25: Since the array is the webapp, the changes are persistent.<br />
Line 27: [1,2,3].to_a returns [1,2,3], and [1,2,3].to_s returns &#8220;123&#8243;.<br />
Line 29: Remove the last value, returning 3 and leaving [1,2] in the array.<br />
Line 30: Remove the first value, returning 1 and leaving [2] in the array.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2011/03/27/on-rubys-expressiveness-the-littlest-microframework-explained/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MacRuby tweaks to your customized .irbrc</title>
		<link>http://www.pervasivecode.com/blog/2011/03/19/macruby-tweaks-to-your-customized-irbrc/</link>
		<comments>http://www.pervasivecode.com/blog/2011/03/19/macruby-tweaks-to-your-customized-irbrc/#comments</comments>
		<pubDate>Sun, 20 Mar 2011 04:59:32 +0000</pubDate>
		<dc:creator>jamieadmin</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=242</guid>
		<description><![CDATA[I started playing with MacRuby this evening. macirb wouldn&#8217;t run with my customized .irbrc and gave the following error:
/usr/local/bin/macirb:60:in `block': No such file or directory - open() failed (Errno::ENOENT)
	from /usr/local/bin/macirb:9:in `block'
	from /usr/local/bin/macirb:7:in `'


If you&#8217;re seeing this, you need to do something like this:
# preserve history across irb executions:
require 'irb/completion'
unless 'macruby' == RUBY_ENGINE
  require 'irb/ext/save-history'
 [...]]]></description>
			<content:encoded><![CDATA[<p>I started playing with MacRuby this evening. macirb wouldn&#8217;t run with my customized .irbrc and gave the following error:</p>
<pre>/usr/local/bin/macirb:60:in `block': No such file or directory - open() failed (Errno::ENOENT)
	from /usr/local/bin/macirb:9:in `block'
	from /usr/local/bin/macirb:7:in `<main>'
</pre>
<p><span id="more-242"></span><br />
If you&#8217;re seeing this, you need to do something like this:</p>
<pre># preserve history across irb executions:
require 'irb/completion'
unless 'macruby' == RUBY_ENGINE
  require 'irb/ext/save-history'
  ARGV.concat [ "--readline"]
end
IRB.conf[:SAVE_HISTORY] = 100
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-save-history"
</pre>
<p>What I changed was to add lines 2 and 5 from that excerpt, making lines 3 and 4 only run if I&#8217;m *not* using macirb. If you&#8217;re getting the same error from macirb, this (or something similar) should fix it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2011/03/19/macruby-tweaks-to-your-customized-irbrc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Managing autossh via monit</title>
		<link>http://www.pervasivecode.com/blog/2011/01/04/managing-autossh-via-monit/</link>
		<comments>http://www.pervasivecode.com/blog/2011/01/04/managing-autossh-via-monit/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 06:19:35 +0000</pubDate>
		<dc:creator>jamieadmin</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[OpenSSH]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=234</guid>
		<description><![CDATA[SSH port forwarding is so useful that sometimes you want to daemonize it, to create encrypted tunnels that never go away. But it&#8217;s not trivial to do this. Fortunately it is possible with a little fiddling, and I did it using monit.

I have two servers, let&#8217;s call them A and B, and I want to [...]]]></description>
			<content:encoded><![CDATA[<p>SSH port forwarding is so useful that sometimes you want to daemonize it, to create encrypted tunnels that never go away. But it&#8217;s not trivial to do this. Fortunately it is possible with a little fiddling, and I did it using monit.<br />
<span id="more-234"></span><br />
I have two servers, let&#8217;s call them A and B, and I want to connect via ssh from A to B all the time, reconnecting as needed to deal with network problems, reboots, or other reasons why the connection might drop. A program called autossh does most of this, but doesn&#8217;t handle reboots. So since I already have monit set up to watch other daemons and keep them from going crazy, I set up a monit configuration to manage autossh. All of this runs on server A; server B just has sshd and a mail server that&#8217;s going to try to deliver mail to localhost:2525 to get mail to server A.</p>
<p>The monit configuration stanza (in monitrc) looks like this:</p>
<pre>check process mailtunnel with pidfile /var/run/autossh.pid
  start program = "/root/start_mailtunnel.sh"
  stop program = "/root/stop_mailtunnel.sh"
  if changed pid then alert
  if failed host localhost port 2525 protocol smtp with timeout 30 seconds then alert
  if 3 restarts within 5 cycles then timeout</pre>
<p>start_mailtunnel.sh looks like this:</p>
<pre>#!/bin/sh
export AUTOSSH_PIDFILE=/var/run/autossh.pid
/usr/bin/autossh -N mailtunnel &#038;</pre>
<p>And that -N is the key to making ssh happily connect and not run a remote shell, which would want a tty on stdin. That&#8217;s how you tell it to just be a port-forwarding connection.</p>
<p>The ssh mailtunnel config just has some port forwarding rules, and &#8220;ExitOnForwardFailure yes&#8221;.</p>
<p>Finally, stop_mailtunnel.sh looks like this:</p>
<pre>#!/bin/sh
test -e /var/run/autossh.pid &#038;&#038; kill `cat /var/run/autossh.pid`</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2011/01/04/managing-autossh-via-monit/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Making Bundler 1.0.0.beta.10 install Nokogiri on Leopard with a newish libxml</title>
		<link>http://www.pervasivecode.com/blog/2010/07/25/making-bundler-1-0-0-beta-10-install-nokogiri-on-leopard-with-a-newish-libxml/</link>
		<comments>http://www.pervasivecode.com/blog/2010/07/25/making-bundler-1-0-0-beta-10-install-nokogiri-on-leopard-with-a-newish-libxml/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 05:26:08 +0000</pubDate>
		<dc:creator>jamieadmin</dc:creator>
				<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=219</guid>
		<description><![CDATA[Okay, now that Bundler 1.0.0.beta.10 is out, you can once again pass build-time options to gems with native extensions, such as Nokogiri. So this supercedes my older instructions for making Bundler 0.8.5 install Nokogiri on Leopard.
So now instead of making a YAML file and referring to it, pass the options like this:

bundle config build.nokogiri \
--with-xml2-include=/usr/local/include/libxml2 [...]]]></description>
			<content:encoded><![CDATA[<p>Okay, now that Bundler 1.0.0.beta.10 is out, you can once again pass build-time options to gems with native extensions, such as Nokogiri. So this supercedes my older <a href="http://www.pervasivecode.com/blog/2010/03/17/making-bundler-0-8-5-install-nokogiri-on-leopard-with-a-newish-libxml/">instructions for making Bundler 0.8.5 install Nokogiri on Leopard</a>.</p>
<p>So now instead of making a YAML file and referring to it, pass the options like this:</p>
<pre>
bundle config build.nokogiri \
--with-xml2-include=/usr/local/include/libxml2 \
--with-xml2-lib=/usr/local/lib
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/07/25/making-bundler-1-0-0-beta-10-install-nokogiri-on-leopard-with-a-newish-libxml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fix for MacBook Pro sudden USB and Ethernet port failures</title>
		<link>http://www.pervasivecode.com/blog/2010/07/24/fix-for-macbook-pro-sudden-usb-and-ethernet-port-failures/</link>
		<comments>http://www.pervasivecode.com/blog/2010/07/24/fix-for-macbook-pro-sudden-usb-and-ethernet-port-failures/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 04:04:03 +0000</pubDate>
		<dc:creator>jamieadmin</dc:creator>
				<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=206</guid>
		<description><![CDATA[I own a 2.16GHz MacBook Pro, which is a little over 3 years old. Over the last year I&#8217;ve had an odd problem with it, which has gotten severe in the last few weeks. The problem was that it would suddenly disable the Ethernet port and the USB ports, disconnecting mounted disks and freezing networked [...]]]></description>
			<content:encoded><![CDATA[<p>I own a 2.16GHz MacBook Pro, which is a little over 3 years old. Over the last year I&#8217;ve had an odd problem with it, which has gotten severe in the last few weeks. The problem was that it would suddenly disable the Ethernet port and the USB ports, disconnecting mounted disks and freezing networked services. The only workaround was to reboot or sleep/wake. I finally found the cause and fixed it last week. My guess is that pretty much all MacBook Pros of similar age and design will develop this problem, so read on if you have a similar issue.<br />
<span id="more-206"></span><br />
The computer itself is a 15&#8243; 2.16GHz MacBook Pro, order number MA601LL, but I&#8217;ll bet that all of the A1150 series will have the same issue, and maybe the later models.</p>
<p>The problem would appear unpredictably, and defied my attempts to reproduce it, with one exception: Netflix Instant streaming would invariably result in a failure in less than 15 minutes of play. I tried updating the Silverlight plugin, and then simply not ever using Netflix streaming, but that didn&#8217;t help.  Eventually I found that running anything that kept the CPU near 100% utilization for a minute or so would trigger the problem. Could it be a thermal issue?</p>
<p>I use <a href="http://bjango.com/apps/istatmenus/">iStat Menus</a> so I was able to easily see that my CPU temperature was over 160&deg;F whenever this happened, and my fan speed was about 6000 RPM. I tried placing something under my laptop to increase airflow underneath it (simulating my wife&#8217;s <a href="http://www.griffintechnology.com/products/elevator">Griffin Elevator</a>), but that didn&#8217;t help. I did some searching to see if that CPU temperature and fan speed were unusual, and found the <a href="http://www.intelmactemp.com/">Intel Mac Temperature Database</a>. It seems like other folks have seen higher CPU temperatures than 160&deg;F without problems, so that probably wasn&#8217;t it.</p>
<p>I decided to dig around a bit to see if 6000 RPM was a reasonable fan speed. Apparently not; several pages I found mentioned that MacBook Pros get uncomfortably hot because the standard temperature to fan speed profile that Apple used wasn&#8217;t enough to keep the laptop cool, and so some people use <a href="http://www.eidac.de/?page_id=6">smcFanControl</a> to increase the minimum fan speed to 4000 RPM. I installed smcFanControl and found that 6000 RPM is the <i>maximum</i> fan speed it allows.</p>
<p>I wondered if maybe my laptop was getting hot, and the fans were working as hard as they could and still couldn&#8217;t keep the temperature under control?</p>
<p>Following that hypothesis led me to <a href="http://forums.macrumors.com/showpost.php?p=7616725&#038;postcount=15">this post in the &quot;Macbook overheating?&quot; thread on MacRumors</a>. Since I&#8217;ve upgraded the hard drive in every MacBook I&#8217;ve owned, I have the tools to open one up already, and the excellent <a href="http://www.ifixit.com/Guide/Repair/Installing-MacBook-Pro-15-Inch-Model-A1150-Right-Fan/499/1">iFixIt Fan Replacement Instructions</a> were almost the same as what I&#8217;d had to do for a hard disk replacement, so I decided to go ahead and open it up and take a look myself.</p>
<p>Here&#8217;s what I found:</p>
<div id="attachment_202" class="wp-caption alignnone" style="width: 310px"><a href="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/1_right_dirty.jpg"><img src="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/1_right_dirty-300x225.jpg" alt="The right fan filter is almost completely clogged." title="1_right_dirty" width="300" height="225" class="size-medium wp-image-202" /></a><p class="wp-caption-text">The right fan filter is almost completely clogged. (click to enlarge)</p></div>
<div id="attachment_203" class="wp-caption alignnone" style="width: 310px"><a href="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/2_left_dirty.jpg"><img src="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/2_left_dirty-300x225.jpg" alt="The left fan filter is also almost completely clogged." title="2_left_dirty" width="300" height="225" class="size-medium wp-image-203" /></a><p class="wp-caption-text">The left fan filter is also almost completely clogged. (click to enlarge)</p></div>
<p>Jackpot. I vacuumed the dust out. Here&#8217;s what it&#8217;s supposed to look like:</p>
<div id="attachment_204" class="wp-caption alignnone" style="width: 310px"><a href="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/3_right_clean.jpg"><img src="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/3_right_clean-300x225.jpg" alt="That&#039;s much better." title="3_right_clean" width="300" height="225" class="size-medium wp-image-204" /></a><p class="wp-caption-text">That's much better.</p></div>
<div id="attachment_205" class="wp-caption alignnone" style="width: 310px"><a href="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/4_left_clean.jpg"><img src="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/4_left_clean-300x225.jpg" alt="The left fan filter is now clean-ish." title="4_left_clean" width="300" height="225" class="size-medium wp-image-205" /></a><p class="wp-caption-text">The left fan filter is now clean-ish.</p></div>
<p>I put it back together, and the problem is gone! Cost: $0.</p>
<p>As a bonus, it runs cooler so it isn&#8217;t painful to use on my lap, and since the fans don&#8217;t have to work so hard, it&#8217;s quieter than before.</p>
<p>So if you have a flaky MacBook Pro of similar age that&#8217;s running strangely hot and your fans are running at full blast, maybe you should open it up and see what your dust situation is. Like I said, my guess is that every single MacBook Pro will experience this problem sooner or later.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/07/24/fix-for-macbook-pro-sudden-usb-and-ethernet-port-failures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Princess and the Pea, as a Cucumber Feature</title>
		<link>http://www.pervasivecode.com/blog/2010/06/01/the-princess-and-the-pea-as-a-cucumber-feature/</link>
		<comments>http://www.pervasivecode.com/blog/2010/06/01/the-princess-and-the-pea-as-a-cucumber-feature/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 20:00:41 +0000</pubDate>
		<dc:creator>jamieadmin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=197</guid>
		<description><![CDATA[Kent Beck tweeted:

User story: &#8220;As a princess I want to confirm my royalty so I get bruised after sleeping on 40 mattresses over a pea&#8221;. Just tell real stories&#8221;

That sounded so much like a Cucumber feature that I decided to write it as one:

Feature: Physical Sensitivity
  In order to confirm my royalty
  As [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://twitter.com/kentbeck/">Kent Beck</a> tweeted:</p>
<blockquote><p>
User story: &#8220;As a princess I want to confirm my royalty so I get bruised after sleeping on 40 mattresses over a pea&#8221;. Just tell real stories&#8221;
</p></blockquote>
<p>That sounded so much like a <a href="http://cukes.info/">Cucumber</a> feature that I decided to write it as one:</p>
<pre>
Feature: Physical Sensitivity
  In order to confirm my royalty
  As a princess
  I want to be very delicate

  Scenario: 40 mattresses on a pea
  Given there is a pea on the bed
  And there is a stack of 20 mattresses on the pea
  And there is a stack of 20 featherbeds on the mattresses
  When I try to sleep on top of the stack of featherbeds
  Then I should not be able to sleep
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/06/01/the-princess-and-the-pea-as-a-cucumber-feature/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unix tip: kill -STOP and kill -CONT</title>
		<link>http://www.pervasivecode.com/blog/2010/04/03/unix-tip-kill-stop-and-kill-cont/</link>
		<comments>http://www.pervasivecode.com/blog/2010/04/03/unix-tip-kill-stop-and-kill-cont/#comments</comments>
		<pubDate>Sun, 04 Apr 2010 01:31:44 +0000</pubDate>
		<dc:creator>jamieadmin</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=194</guid>
		<description><![CDATA[Pretty much every Unix user knows about the kill command, and most know about &#8216;kill -KILL&#8217; aka &#8216;kill -9&#8242;.
But do you know about kill -STOP and kill -CONT?

I&#8217;m not sure of the exact mechanism (kernel vs. user process) but everything I&#8217;ve used it on on a Mac OS X machine has responded to it in [...]]]></description>
			<content:encoded><![CDATA[<p>Pretty much every Unix user knows about the kill command, and most know about &#8216;kill -KILL&#8217; aka &#8216;kill -9&#8242;.</p>
<p>But do you know about kill -STOP and kill -CONT?<br />
<span id="more-194"></span><br />
I&#8217;m not sure of the exact mechanism (kernel vs. user process) but everything I&#8217;ve used it on on a Mac OS X machine has responded to it in the same way. So you may find a process that doesn&#8217;t do this, but I haven&#8217;t found one.</p>
<p>Basically <code>kill -STOP 1234</code> will pause the process with pid 1234, and <code>kill -CONT 1234</code> will resume it. It&#8217;s as if you can sleep individual applications instead of your entire computer.</p>
<p>It&#8217;s simple, but you can probably imagine why this would be useful. Want to keep Firefox with 45 tabs open, but you&#8217;re not using it for a while and you want to save battery life? Pause it. Pretty much anything like &#8220;I don&#8217;t want to quit and then re-launch this but I wish it wasn&#8217;t using a bunch of CPU time while it idles&#8221; is a good candidate.</p>
<p>Remember that this means your app my time out when it is resumed, as if you had slept your laptop. So network connections it had open when you paused it may be broken when you resume it. So pausing Terminal.app with a bunch of open ssh connections to remote servers isn&#8217;t going to work too well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/04/03/unix-tip-kill-stop-and-kill-cont/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to make Machinist and Autotest coexist</title>
		<link>http://www.pervasivecode.com/blog/2010/03/23/how-to-make-machinist-and-autotest-coexis/</link>
		<comments>http://www.pervasivecode.com/blog/2010/03/23/how-to-make-machinist-and-autotest-coexis/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 03:47:22 +0000</pubDate>
		<dc:creator>jamieadmin</dc:creator>
				<category><![CDATA[agile development]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=189</guid>
		<description><![CDATA[If you&#8217;ve tried to use Machinist and autotest (part of ZenTest) you have probably seen this exception that prevented you from using it: 
`method_missing': No sham defined for name
It&#8217;s discussed in the machinist Google Group as well.
It&#8217;s because of a wacky hack that&#8217;s part of Machinist that overrides Module.name so you can do Sham.name, but [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve tried to use Machinist and autotest (part of ZenTest) you have probably seen this exception that prevented you from using it: </p>
<pre>`method_missing': No sham defined for name</pre>
<p>It&#8217;s discussed in <a href="http://groups.google.com/group/machinist-users/browse_thread/thread/9af4aa2243ae0368/4e9bba83113ace20">the machinist Google Group</a> as well.</p>
<p>It&#8217;s because of a wacky hack that&#8217;s part of Machinist that overrides Module.name so you can do <code>Sham.name</code>, but ZenTest expects Module.name to do what it does normally.</p>
<p>I have a fix for this.<br />
<span id="more-189"></span></p>
<p>I sent notahat a pull request via GitHub, so hopefully it&#8217;ll be merged by notahat into the official machinist gem, but until that happens you can try mine. I published the gem as JamieFlournoy-machinist to rubygems.org.</p>
<p>Try &#8216;gem install JamieFlournoy-machinist -v 1.0.6&#8242; and see if it works for you. It does for me with ZenTest 4.2.1, autotest-rails 4.1.0, and a Rails 2.3.5 project.</p>
<p><a href="http://github.com/JamieFlournoy/machinist">(my machinist fork on github)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/03/23/how-to-make-machinist-and-autotest-coexis/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

