MicroISV Site: Bingo Card Creator

I am very interested in reading about entrepreneurship, particularly Micro ISV’s. I have been very impressed with Patrick McKenzie’s MicroISV blog. Patrick’s blog is about his company which sells a Bing Card Creator. It’s amazing how many details he’s willing to share about his company, and the strategies he is using. He discusses his profits, his costs, his advertising, in short all of the relevant details of his business are posted there on his blog. He has especially good ideas about Search Engine Optimization and Search Marketing in general. If you are interested in starting your own business, I highly recommend Patrick’s blog. Of the twenty or so startup related blogs I read, it’s one of the best.

Google Reader Rocks

I’m constantly looking for software or utilities that will improve my productivity. From trying out new languages to learning new development tools, nothing is out of bounds. One thing I’ve learned over the years is that there aren’t any magic bullets out there. Nothing will magically make the pain points go away. Yet every now and then I come across a piece of software that is so well designed I wonder why everyone isn’t using it. Google Reader is that application for me. I am thoroughly impressed with how well it works for keeping up on my feeds.

One of the biggest benefits of Google Reader for me is that it’s a web application. I have four computers that I move back and forth between pretty regularly (a work desktop, a work laptop, a home desktop, and a home laptop). So it’s important to have everything available over the network for me. All of my important code, scripts, and documents are kept in a subversion repository so I can easily move between machines and access them.

Feed Readers on the other hand have been a big problem for me. I’ve bounced back and forth between several different options. Online feed readers, clientside feed readers, manually visiting sites. Of the Online feed readers I’ve tried before Google Reader, I haven’t liked the flow. They have all felt bulky or hard to use. The desktop clients are typically more fluid but either aren’t cross platform (OS X on my laptops and Windows XP on my desktops) or the pain of trying to manage the feeds across multiple machines has been too much. The final option of visiting the sites manually suffers from scaling problems. I usually forget to visit sites after a period of time if the author hasn’t updated in a while.

Google feed reader though solves all of those problems. It’s a network application, so it’s natively available on all the machines I use. The interface is amazingly slick, and very easy to work with. It of course also makes it so I can scale the sites I’m reading by at least an order of magnitude over what I can do manually. If you haven’t given Google Reader a try, I highly recommend it.

Interviewing and Hiring programmers

I’ve seen and read a lot of discussions about hiring programmers. Most people claim to want great programmers, but few people know how to even marginally separate the good from the bad. “Great” is a loaded term, and it means different things to different people. What I want to focus on is how to hire competent programmers who can in fact produce a solution and produce working code. Then I leave it to the reader to determine how high they want their threshold set.

Let me start with a story about what I consider the best hiring process I’ve ever been through. Something I’ve modeled subsequent hiring processes on. I don’t necessarily think this process was perfect, but I think they are erring on the right side of the equation. First I’ll give the narrative of the technical screening for the hiring process and then I’ll go back and explain what I liked and didn’t like about it.

I heard through a friend of mine that a prominent web analytics company was hiring in my area. The position sounded very interesting and with my frustration at my current job running at an all time high, I decided what the heck, let’s give it a go. I submitted my resume and within a day or so I had a recruiter on the line talking to me about the position.

The first stage of the interview process consisted of a set of verbal brain teasers given to me over the phone. I managed to work through them and come up with the right answers. After that we talked for a while about what the position would entail and how I would fit into the new company. The next day I received another call from the recruiter, he told me they would be moving me to the next level of the recruiting process. The next step it turned out was another set of brain teasers, this time a bit harder, but still administered over the phone. After making it through that set of brain teasers he told me they wanted to schedule a face to face interview.

So he scheduled an interview with the development manager I would be working for. When I showed up on the appointed day at the appointed time, the manager took me to a conference room with glass windows, a table, chairs, and a white board. He then handed me a printout of a technical problem and asked me to pseudo code the solution on the white board. He told me he would pop in every 10 minutes or so and answer any questions I had about the system. He told me up front not to worry about syntax issues or compiler errors or the like. He wasn’t concerned with that level of detail, just pseudo code a solution to the problem, but make sure it fundamentally solves the problem. After I was finished, we would talk through my solution. With that he left me alone in the room with the printout and the blank white board staring back at me.

I have to admit, my initial feeling was pure unadulterated panic. How hard was this problem? Were they measuring how long it would take me? What if I took too long? Was I good enough to solve this on a white board like this? Was I good enough to solve it at all? I took a minute and tried to calm my heart and slow my breathing. Make sure you are breathing in and out is some of the best advice I’ve ever heard 1.

So after calming myself down, I began reading through the problem. I had never seen this particular problem before, but it was an ACM problem one month. Here is a link to the problem. I’ll be assuming you’ve read the problem from here on. After reading through the problem a few times, and making sure I understood it, I sat there and thought through the problem for a few minutes. After thinking about it, and having a chance to ask my first questions I started pseudo coding a solution on the board.

After about 30 minutes my solution was complete and the development manager came back in and looked over my pseudo code. As a side note, I do my pseudo coding in Ruby because the syntax is so clean and concise, so I had to do some explaining to the manager about a few of the character symbols I used. We talked for a while about my solution and then he quizzed me on how it worked.

Once the development manager was satisfied that my solution would indeed work, he started asking me optimization questions. “How can you make it run faster?” We went through a few things and tightened up my code. Then he asked me again how I could make it run faster? I had already been through a first round of optimization, so now I had to think for a bit. After thinking for a little bit, I came up with another set of changes that would make the code run more quickly. We talked about that for a while, then he asked the question I was afraid he would ask again. “How can you make it run faster?”

There is that panic making a come back, what was I missing? Then he asked me a leading question, “Do you think you could use the results of your first 12 hour run to do some optimizing?”. D’oh, as soon as he said that the solution was blindingly obvious. Of course you can, the first run would define a series of shifts for the balls, after you’ve run it the first time you can just apply the same shift pattern again without running the full simulation. So we talked through how I would implement that for a while.

Then he said “ok, I’m going to ask you for one final level of optimization. No one has ever gotten this, so I don’t expect you to, but I like to see if anyone can figure it out”. After setting the stage like that I was fully involved. Panic? Hah, now I’m having delusions of grandeur, maybe I can figure it out!

“What if we made this into kiosk software and it has to run in the time it takes for someone to type in the number of balls and get an immediate response. How would you make it run that fast?”. Knowing this would take a while to compute especially at the upper bound, I asked him if it would still be bounded by the 27 to 127 constraint as the initial problem. He answered affirmatively. After thinking about it for a moment, the obvious solution is to pre-compute the number of 24 hour periods for each number 27 to 127 and simply ship the kiosk software with a built-in lookup table.

He then asked “What if we removed the 27 to 127 bounds and said it has to be able to solve any entry entered, but still retain the same speed and responsiveness as our last solution for anything that’s already been solved.” From pre-computing to this step was pretty easy. Now you just need your storage mechanism to be extendable so you can lazy compute any value and store the results once it’s already been computed.

After getting through all of that, we talked a little more about the position, and then he showed me around the place. In the end they offered me the job.

The reason I went through that process in as much detail as I did was to give people some inkling of what a solid technical interview is like. I left a lot of detail out because it’s too cumbersome to type it all and my memory isn’t perfectly accurate. However let’s cover the good and the bad of that process.

First, brain teasers. A lot of companies use them, but I don’t think they have any place in a modern programming interview. Solving brain teasers is more about whether you are good at brain teasers than how good of a programmer you are. Case in point, I know several people who are great at brain teasers but are terrible programmers. Solving a brain teaser has no predictive value when it comes to programmers. That being said brain teasers are a great thing to give your HR guy to do if they require you to let them do the first round of screenings. The drawback is you could alienate or lose possible candidates who can’t solve brain teasers but are still good programmers.

Second, the real gem in this process was actually solving a technical problem. It seems obvious that when you are going to buy a car you test drive it. When you are buying a pair of shoes you try them on for fit. When hiring a programmer, you need to see how they program.

Ultimately that is the real point of this long winded blog post. There are two ways to administer programming problems to applicants. The easy way is to mail the problem to them and have them e-mail back a solution, then if you like what you see, bring them in and discuss it with them. There are several benefits to the e-mail option. First, your applicant will freak out less because they aren’t on the spot. Second, you get to see actual code. The biggest draw back though is how easy they can cheat on the test. Most of these problems are just one Google search away. The other problem is they may not even solve it themselves. They may just cut and paste someone elses solution or have a friend do it for them. Most of those risks can be alleviated by bringing them in to talk about their code. Ask them why they designed it the way they did. Talk through the implementation details with them. Ask them about alternative designs.

One key to this process for my last company was having an in-house programmer competition. We all solved the same problem the applicants were solving, then we had to solve it different ways. The fastest solution, the least amount of code, the most elegant, etc. Doing the in-house competition made all of our programmers understand the problem the applicants were being asked to solve in great detail. That way when an applicant came in, everyone could ask intelligent questions about their solution. It also meant we could pass around e-mailed solutions to the team and everyone had a solid opinion about whether the solution was good or not.

If you don’t like the e-mail option you can have applicants solve the problem on the white board, but it’s important that you emphasize the pseudo code approach. If you expect syntactic perfection on a white board, you are probably setting the bar too high.

The ball clock isn’t the only problem to give to candidates. There are a number of places you can find less publicized problems to use. You can search for ACM Problems or you can go to TopCoder and take some of their problems. Before you give it to any applicants though, make sure some of your internal programmers solve it, some of those problems are deceptively hard and may not be suitable for an interview.

The key to a good programming problem though is something you can talk with the applicant in detail about. You and your team need to come up with some really hard questions to ask them about this problem. If they don’t get them all right that’s ok, usually you and your team have had a lot more time to think about this problem than an applicant. It’s just important for you to probe their thinking process.

A quick digression on some other interviewing tactics people use. Don’t expect programmers to have memorized every little technical detail in every corner of the language or platform. I’ve often seen interviewers ask details about incredible minutae, and then get a self-satisfied smirk when the applicant can’t answer it. Yet I know for a fact that if the roles were reversed the applicant could stump the interviewer with some technical minutae as well, particularly if they got the chance to prepare for it. This is a relatively sticky point because many technical details are important and any programmer that works in a technology all the time should know them. Others are arcane bits of lore that even the creators of the language have to look up. There are no hard answers here, but always try to avoid those arcane knowledge questions. They generally have little predictive power when assessing an applicant and usually just instill resentment.

In concluding you need to have a real technical screening process in place. Many applicants will judge you just as harshly as you judge them. If I interview somewhere that doesn’t have a real screening process, I know I will be working with incompetent programmers. As a programmer, the last thing I want to do is walk into a company where I’m constantly fixing someone else’s mess. So unless I’m being brought in to build the technical screening process, I’m going to pass on a company that doesn’t do good screening of applicants. Hopefully after reading this, you’ll be able to conduct a screening that will at the very least sift out the bad programmers or the programmers incapable of producing working code. The sad fact of the matter is, most managers wouldn’t believe just how many incompetent programmers there are in the world.

Fixing the Leopard upgrade problem.

I ran into the Leopard upgrade problem that others have been reporting. The problem happens after you do a successful upgrade and the system reboots. It then hangs at the blue screen prior to login. Other people have wiped the disk and proceeded with a fresh install. While I could have done that, I didn’t want to take the time to rebuild my machine totally from scratch. After doing a Google search for “leopard upgrade problems” I came across this comment on digg:

by indiekiduk 10 hours ago
This problem appears to be an unfortunate incompatibility with ShapeShifter software you might have installed.

Do this and it fixes it (worked for me)

1. Reboot into single-user mode (hold Cmd-S while booting machine)
2. Follow the directions OSX gives you when you get to the prompt (I think these were them - just type the two commands it tells you to):
fsck -fy /
/sbin/mount -uw /
3. Remove the following files:
rm -rf /Library/Preference Panes/Application Enhancer.prefpane
rm -rf /Library/Frameworks/Application Enhancer.framework
rm -rf /System/Library/SystemConfiguration/Application Enhancer.bundle
rm -f /Library/Preferences/com.unsanity.ape.plist
4. Exit, to continue booting normally
exit

I checked the locations first, and sure enough, those files existed on my system as well. After deleting them I booted into Leopard just fine. There are a few typos in the paths above, but I decided to copy the post from Digg verbatim. The original link is here. Hopefully this blog post will help prevent a few people from needlessly nuking their hard drive.

Ruby jumps another spot on TIOBE

Ruby advanced to 10th place this month on the Tiobe index. It moved up to 2.519% percent of the market. It will be interesting to see if Ruby can penetrate into the top 8. The percentage drops of the languages in the top spots are interesting to note.

All Customers are Criminals

Whatever businesses do there are consequences. Even the seemingly smallest procedures can affect your customer base, your employees in ways you didn’t intend. One specific example that has occured to me lately is the purchase of gasoline. It used to be that you’d pull up to a gas pump, put the handle in your car, select your grade of gasoline and they’d automatically activate the pump for you. After you had finished pumping your gas, you’d go inside the store and grab some items that were appealing, and then pay for the items and your gasoline.

Now when you go to a gas station you have two choices, you can pay for your gas by credit card or you can go inside and prepay with cash. I like to purchase everything with cash, it’s how I manage my budget. I have a specific place in my wallet for my gas money, and a different place for my spending money. I don’t have to balance anything, and I can easily assess if I’m running low on my budget by checking my cash on hand. It’s a system that has worked well for my wife and I for years. Yet suddenly I’m finding that filling up with gasoline is becoming more and more of a pain. To pay with cash it means I usually have to go wait through the line inside the store twice. Once to give them enough cash to cover a fill up, and then I have to go back to get my change. The hassle is enough to make me consider leaving my gas money in my bank account so I can just use my debit card to fill up.

The obvious reason the gas stations make people pre-pay is so they can eliminate gas-n-go, people who fill their tank then leave without paying. Here’s the problem with that philosophy though. By tightening the belt on those who might gas-n-go, they are treating all of their customers like criminals. So now they’ve raised the transaction cost of using cash. Raising the cost of the transaction tends to push customers towards a different mode of payment. So now, let’s say everyone pays with Credit or Debit cards before they pump their gas. All of the sudden people have no reason to go into the store, which means you lose all the incidental purchases they would have made while they were inside the store. People will still go inside the store, and people will still buy things, but when people are paying for their gas with a credit card, they will only go inside if they needed something specific. Those people may still buy something they didn’t intend simply because they saw it, but all of the people who don’t go in the store won’t buy anything incidental. I talked to one gas station employee and she incredulously told me that three people had driven off without paying for their gas in the last three months. Three people?!? I had thought we were dealing with some sort of epidemic. That’s the cost of one tank of gasoline per month. I would bet cold hard cash that these policies are actually causing companies to lose a lot more revenue per month than they are gaining.

Ultimately I suspect the business model of treating all of your customers like criminals isn’t the best or most efficient way to serve customers. The companies that really truly do treat their customers well seem to be very resilient even in the face of tough economic conditions. I hope that some companies will get their message and realize that by saving a few bucks in stolen gasoline, they are losing revenue in other ways. It’s entirely possible that I’m off base here and companies lose more in gas than they gain in incidental purchases, however one thing is for sure. Unless I can find a gas station that doesn’t make me prepay for my gas, I’ll soon join the rest of the world and purchase my gas with plastic.

Technorati ownership post.

This post is to verify to technorati that I own this blog.  You can safely ignore this post.

Technorati Profile

The Rise of Ruby

Apparently I’m not the only person watching the Tiobe index, because other people have been commenting on Ruby’s new position in the list. A couple of things to note, I’ve been watching the Tiobe list religously for over a year now. When I started watching Ruby was somewhere down in the depths of the unknown languages. I don’t recall it’s exact position, but I remember waiting and hoping it would cross the threshold in into the top 20 languages. After watching it’s meteoric rise for the last year I have been amazed at how quickly it has climbed the chart.

It’s interesting to note that last month Ruby was at the 12th slot on the list, just above PL/SQL. I don’t remember the exact percentage but Ruby was only at around 1.4% and SAS was around it’s current position of 2.2%. I thought at the time that it would take Ruby several months to cover the distance to SAS, but it seems to have made a huge jump this month up to 2.3%. Now remember in their estimation that means that ruby is approximately 2.3% of the programming market!

I wish TIOBE would maintain a historical index of the data so we could see what the positions and percentages were for any given month. And unfortunately the wayback machine only shows as far as April of this year. However when you look at December 2005, there are some interesting peculiarities. Dec. 1 - Dec 3 of 2005 the TIOBE index lists Ruby as 21st in the list with 0.434% of the market. However after December 3 and for the rest of the December Ruby is listed at 26th with 0.317% of the market. I’m not sure what’s going on with their statistics here, but they seem a bit wonky (unless of course somehow the wayback machine was storing it incorrectly).

Let’s use the most conservative number and say that last December Ruby was at 0.434% market penetration where now they are at 2.334%. That represents a 538% increase! I’m sure that Ruby’s growth will slow down at some point, but in all honesty I think those numbers probably lag behind a bit right now. A year ago very few people even know about Ruby, these days I can talk to almost any programmer, even a C# guy and they’ll know what Ruby is. A large chunk of them will even have some interest in learning Ruby. I don’t say even a “C# guy” to lambast the C#’ers, but more to illustrate that a group that isn’t really known for being well versed in open source programming languages is becoming more and more aware of Ruby.

This last year of Ruby has been interesting and exciting at times. It’s becoming easier and easier to convince management that Ruby is acceptable in the enterprise. At my current company Ruby is the de facto language of choice. In the coming year, with the growing awareness of Ruby, will 2007 mark the Rise of Ruby in the mainstream?

Inaugural User Group Meeting

We kicked off the first Layton Ruby Brigade meeting last Tuesday. I was a bit nervous that nobody would show up other than Ceaser, but I was planning to have it either way. We ended up getting nine people to come, although three of them were from the Utah Valley contingent. Kevin Tew, Pat Eyler, and Pat’s son made the seventyish mile trek to our neck of the woods. We also had Aaron Toponce and Kevin Carter from the Ogden area Linux User Group show up. Finishing it out we had Russ Reed a local SQL Server Developer and my brother Torrey show up. Aaron, Kevin, Russ, and Torrey were all new to Ruby.

My initial thoughts were to prepare some presentation, but in the end I’m glad I didn’t. Any presentation I had prepared would probably not have been geared towards someone new to Ruby, and would have ended up getting scrapped. I also run a mailing list with about 30 people that I know in Northern Utah or that I have worked with over the years. I got several people who said they would probably come to another meeting if they had more notice next time (I forgot to send out the announcement to that list until the day of the meeting).

I have to throw a thanks out to my lovely wife who was kind enough to let us turn the living room into a meeting room with a couple of small tables, quite a few chairs and a projector I borrowed from the company I work for. As far as the pizza and refreshments, it looks like I bought enough to feed a group twice that size. For nine people we had four pizzas and about 12 liters of soda. I also made some habanero chili cheese dip. So if you missed the inaugural meeting you missed some good food. I suspect that in the future we won’t have quite as nice of a spread, but we’ll keep up with the pizza and soda.

After we had introduced ourselves and gotten a little acquainted we headed down to the living room to start talking about Ruby. Initially we fired up an IRB session and started talking about Ruby. I have to say, when confronted with a vast topic like explaining Ruby from scratch, it can be hard to know where to start. Once we got rolling though and people started asking some questions the discussion moved along more smoothly.

After some general discussion Kevin presented a quick project he hacked together to help him study words for the GRE. Going through the source code and talking it over really helped move the discussion along. It was really nice of Kevin and Pat to come all the way to our meeting. It was nice to have some people with more experience at running a user group.

After Kevin’s presentation, Pat showed us a framework he built for processing log files. Again having working code to discuss and talk through really propelled the meeting forward. During Pat’s presentation people were really starting to open up and ask a lot of questions about Ruby and it’s syntax and structure.

After his log file presentation Pat moved into a discussion about RubyInline. When I saw what could be done with RubyInline, I almost had to hold my jaw up. RubyInline is very impressive, and definitely something I could have used in the past. RubyInline allows you to define a class in say C, and it will automatically compile the class with C, but you can still use it within your Ruby program. But RubyInline does this with multiple languages. What was really nice was how simple and clean the interface was, and just how easy it makes it to solve some specific algorithm within Ruby but get the benefits of C or Fortran.

Overall I was very pleased with the meeting. It was great to meet people from the local area, and at the same time do something that will help drive Ruby as a language forward. Having done it now there are a few things I would do differently.

First of all, there is a tremendous amount of interest in Ruby as a language right now, so I would be more prepared to have people show up who know nothing about Ruby. Someone who takes the time to come to a Ruby User Group meeting but doesn’t know Ruby is someone who is very serious about learning Ruby. These are great people to really spend time helping.

Second, I would have a lot more prepared code to talk about. I would have some code that is relatively simple, up through relatively complicated code. I really enjoyed seeing code written by other people, even when the code is simple you encounter different ways of solving problems than you would do if you were solving the problem. When you run across code that embodies different thought patterns than your own it’s good to understand and learn those thought patterns. I am constantly amazed at how much I learn simply by reading other people’s code.

Finally, be open to letting the meeting wander away from some rigid presentation schedule, really interesting discussion happens when you just let it.

Thanks to everyone that helped make this meeting a success. We are probably going to move to meeting every two weeks instead of once a month, which is actually better for people who are learning. I think next time we’ll tackle some of the problems from the Ruby Quiz (thanks for the idea Pat).

New Ruby User Group

We (Ceaser Larry and I) are starting a new segment of the Utah Ruby User Group called the Layton.rb. Ironically our first meeting will be held in Clinton, but we expect to find a place in Layton to host the meeting ongoing. The meetings will be held on the first Tuesday of every month, which means the first meeting will be held Tuesday, December 5th. I’m pretty excited about this, because I enjoy talking with people about technology, and it’s very exciting to meet people in the local area who like Ruby. If anyone reading this is interested and lives in the Layton Utah area, drop me an e-mail at nurug.closure@recursor.net.