L-39 R/C Jet on the way…

May 4th, 2008

Spring is in the air in Salt Lake City, so it’s finally warm enough to get back into R/C flying. To that end, I ordered the new Electrifly L-39 electric ducted fan (EDF) jet. It’s getting great reviews, and I’m excited to fly it. I’ve read that the stock brushless motor is underpowered, so I’m looking into motor upgrades. I’m considering the HXT 2040 4850kv from HobbyCity.com, which ought to be a bolt-on replacement for the Ammo 3500 inrunner the plane comes with, but I’m worried it won’t give an appreciable power boost.

Stay tuned for more info, but in the mean time, check out this video of the L-39 flying with a pair of F-27 Strykers (which I have also built and flown, if you follow this blog):

And here’s the official Electrifly advertisement for the L-39:

April 2008 LDS General Conference Podcast Updated

April 9th, 2008

I’ved updated my LDS General Conference podcast to include the sessions from the April 2008 conference. For those of you that are already subscribed, you shouldn’t have to do anything — your iTunes or podcasting software will automatically download the newest sessions. For those of you who are not subscribed yet, you can find instructions on my General Conference Podcast page.

Happy podcasting!

Unbricking Your iPod Touch with the Manual DFU Procedure

March 19th, 2008

If you are as curious as I am, you’ve probably managed to brick your iPod touch by now. I bricked mine within 24 hours of owning it. It happened sometime after I installed Apollo and changed the root password using SSH and the passwd command. After I did that, my SpringBoard process stopped working, and was continually getting restarted by launchd because it was crashing consistently (according to “ps -A”). Nice loop really! Anyhoo, I renamed the /System/Library/CoreServices/SpringBoard.app/SpringBoard binary to SpringBoard.bak (so launchd would quit trying to restart it), and ran it myself with ./SpringBoard.bak. I got a really funky error message like this:

ABORT: Unable to register "PurpleSystemEventPort" port, 1103 unknown error code

Now that is a cool error message! (note to self: Use random colors in future error messages).

At one point, I was able to run SpringBoard on the command line and it would stay up, and I could use the interface. Here’s a cool trick: Run SpringBoard from the command line over SSH, and then Ctrl+Z it to suspend it. Notice that your UI is totally frozen on the iPod. Cool stuff! Type “fg” and the UI comes back to life. This much fun should be illegal.

At this point, my Windows XP computer would no longer make the happy “ding dong” sound when I plugged the iPod into the USB port. And, of course, iTunes could no longer detect the iPod. D’oh! This is when I started to get a bit scared. I googled for an iPod touch reset utility like I had used on my 1st generation iPod Nano, but no luck.

After some googling and some help from the good folks on #iphone, I learned that I needed to get the iPod into “DFU mode”, which is a special mode that will indicate to iTunes that there is a bricked iPod that needs to be restored. Here’s the procedure to manually put the iPod Touch into DFU mode:

  1. Turn on your iPod (in my case it would only get as far as displaying the Apple logo
  2. Hold the power and home buttons down (the iPod will power off after 10 seconds, but keep holding those buttons down)
  3. After the iPod powers off, release the power button (but keep holding the home button down)
  4. After a couple more seconds, you should hear that magical “ding dong” that means the iPod is coming back alive, and that Windows has detected it. You may even see a little “New hardware” popup in Windows. It is now safe to release the home button, and your iPod is in DFU mode.
  5. Now iTunes will see it as a DFU’ed iPod and should ask you to automatically restore its firmware.
  6. iTunes has to download the new firmware, and it takes a while, so go make a sandwich.

In case you’re wondering, the “power button” is the one on top, and the “home button” is the one under the screen.

Happy iUnBricking!

How Fast are the Google Street View Cars?

February 27th, 2008

Well, about this fast:

Nifty Log Watching Command

February 21st, 2008

Have you ever wanted to watch all the logs in /var/log and sub-directories on your Linux box? Well, I have, and normally I just use tail -f *.log, but that doesn’t work because some log files don’t end in “.log”. Furthermore, you can’t use tail -f * because some of the files can contain non-printable binary data (like .gz files), which would mess up your terminal. So, I whipped out this little command today to find all the text files in /var/log (and sub-directories too) and run tail -f on them:

find /var/log | xargs file | grep text | cut -f 1 -d : | xargs tail -F

When just about anything happens on your Linux box, you’ll see it in near real time with this bad boy. Oh, and you’ll probably need to run it as root or at least use sudo.

Edit: I used tail -F instead of tail -f so tail will notice if the log file gets rotated out from under us (thanks Byron).

Enjoy!

The Truth About Software Requirements

January 24th, 2008

I am a computer programmer by profession. In my personal time, however, I am a computer programmer. The difference between the two: requirements (or the absence thereof).

In my industry, software requirements are considered a big deal by nearly all of my users, especially the paying kind. In the 5 years I’ve been working in this industry, I’ve learned five lessons that I’d like to share with my readership (yes, all 3 of you, not counting family).

Lesson 1: Requirements Change

Duh. Everyone knows this. If you’re a great computer programmer, you cope with it by writing flexible code and having a positive attitude. What people don’t know is that changing requirements are really just a symptom of a deeper problem, which I’ll cover later. The lesson here is that you must be flexible, but you already knew that. So, on to…

Lesson 2: Requirements are a Front

Software requirements exist for one reason: People are sick of crappy software. Several years ago, some well intending but misguided people set about to solve the “crappy software problem” by creating a process to control software development more closely with carefully crafted and well managed requirements. Who can blame them? If users knew how to write good software, they would do it themselves. They certainly wouldn’t pay some “socially awkward” person who yammers about closures and list comprehensions. But since they don’t know how to write software, they have to manage those who do. I’m referring here to “the paying kind” of users I mentioned before. I should point out that I’m not talking about shrinkwrap software here, but rather custom development projects with big price tags.

So what’s the front? The front is that the customer knows what he wants, and he desperately wants to communicate that to you, but he only has this crippled 1200 baud modem of a language called “requirements.” This puts you, the programmer, in interpreter mode. Your job is to find out what he really wants and translate that into a usable product. This leads me to…

Lesson 3: You, The Programmer, Must Control the Requirements

Because great programmers recognize their role as an interpreter, translating requirements into what the customer really wants, and translating that into code, you have to be in charge of the requirements. This means that once in a while, you have to go out on a limb and say things like, “Mighty customer, sir, your requirements document says A, but I think you might like B better.” Sometimes you might even have to implement and demonstrate the feature to him first. This is a risky place to be, but it’s where you have to go if your software project is to be successful. This means you actually have to think about what the customer is asking for. Yes, great programmers don’t just translate requirements into code, they go behind the requirements and they control the requirements by gently nudging them in the direction that the customer really needs.

This means you’ll be wrong sometimes. That’s the price you pay to have a successful software project. If you find that you are wrong too often, you probably don’t understand your customer well enough, and some homework is in order. Stop controlling the requirements until you understand your customer fully.

By the way, very few programmers can do this right all the time. I only know a few, and I’m not one of them yet. Most programmers will simply translate requirements into code, and then get very upset when their product is thrown away or rejected by the customer (even if it “satisfies” the requirements”). This is all too often the case because the requirements were bogus in the first place. Truly great programmers, on the other hand, will not only satisfy their customers, but will exceed expectations by delivering a product that gives the customer something they didn’t even know they needed (pay attention managers: that means more revenue), but now can’t live without.

Let’s take an example from the shrinkwrap world: A couple years ago, no one would have thought they needed a $500 cell phone, but now 4 million people just have to have one. Why? Because Apple figured out what people really wanted, before people even asked for it. Do you think some Apple customer handed Steve Jobs a requirements document to build the iPhone? Yeah right.

Lesson 4: The Only Real Requirement

In the end, there is only one real requirement, and it’s quite simple: The customer should get what he wants, and also what he needs. Sometimes you, the programmer, have to help the customer realize that what he wants is not what he really needs, or that what he needs is above and beyond what he wants. This takes people skills. Some customers even want something that is totally at odds with what they need. These people are rare in my experience. You may have noticed that I used the word “gentle” above. That is for these customers.

You have to go behind the requirements to figure out the real needs of your customer. If you don’t, you will fail, even if you follow the requirements to the letter. I should say: Especially if you follow the requirements to the letter. In my experience, implementing the requirements is about 30% of the total effort on a software project. The other 70% is spent discovering and implementing the things that the customer really needs.

Lesson 5: Good Requirements Can’t Replace Good Programmers

Some people seem to think that if you write your requirements well enough, you can afford sub-par programmers. This is simply not true. I don’t care how good your requirements are. I don’t care how much work you did to make them perfect. If you hand them over to crappy programmers, your project will fail. Period.

The only way to run a successful software project is to employ the best people. Never think that if you apply enough rigorous process and manage requirements well enough that you can compensate for having crappy programmers on your project. Nothing can compensate for crappy programmers.

Remember what I said about 30% vs 70%? Good programmers make up the 70%, even if you have perfect requirements (hint: you don’t have perfect requirements).

Happy Coding!

Now that you know what I know, get out there and find out what your customers really want! Oh, and don’t expect to find the answer by just asking them.

Good luck!

P.S. I mentioned a “deeper problem” in my first section. Did you figure out what it is? I hope so.

Qt Stylesheets

January 17th, 2008

I’m a new convert to Qt’s stylesheets. They make customizing your Qt GUI much easier than other methods (like QPalette). Recently, I responded to a request for comments from Trolltech, and I thought my fellow GUI developers might be interested in it.

These are my humble suggestions to Trolltech for improving Qt stylesheets:

I use stylesheets extensively for both tweaking and completely changing the look of a widget. By far, the most common thing I do with stylesheets is set the border of QFrames. They make it so easy to do this, for example:

border: none;
border-bottom: 1px solid black;

I also use them a lot for QFrame background colors. I find it much easier than messing with QPalette, especially when it comes to alpha transparency, background images, and gradient backgrounds.

My number 1 request: Let us reference an external CSS file in our stylesheet. In my current project, I had to patch designer so I could apply the same stylesheet to all my UI files, and actually see that style in Designer while working with it. If I could refer to an external file, I would make each Designer form point to a single stylesheet file (foo.css or :/foo.css), such that I could use a global stylesheet for all forms in my project and actually see how it will look in Designer before building and running my program.

My number 2 request (much less important): Make it easier to change single elements of a stylesheet programmatically. I often have the case where, for example, I want to change a blue gradient background to a gray one (say, when my widget is disabled). My stylesheet also has dozens of other settings that I don’t want to change (like border color, fonts, etc). It would be nice if I could access elements of the stylesheets like a DOM tree, and modify them in place without having to do search and replace on a QString. Currently the way I do it is with CSS comments. I place a START and END comment and then do search and replace to modify styles programmatically. It’s a hack, and I would like more fine-grained control than that.

In short, stylesheets are absolutely fantastic. I love that you have taken a wildly successful web concept and merged it into the world’s best GUI toolkit. Thank you Trolls!

These words of mine come from:
http://labs.trolltech.com/blogs/2008/01/11/tale-of-an-artist/#comment-16393

Using QRect with QHash

January 17th, 2008

In Qt 4.3.3, I found myself needing to use QRect instances as a key in a QHash. However, Trolltech provides no qHash() implementation for QRect, so I implemented this one, and I think it ought to cover the most common uses of QRect. What do you think?

CODE:
  1. uint qHash(const QRect &rect)
  2. {
  3.     uint code = 0;
  4.  
  5.     code |= (rect.x() <<16);
  6.     code |= (rect.y() & 0x0000ffff);
  7.     code ^= (rect.width() <<16);
  8.     code ^= (rect.height() & 0x0000ffff);
  9.  
  10.     return code;
  11. }

Preliminary testing seems indicates that it produces a fairly good distribution of hash codes. In this case, I'm defining "fairly good" as, "I haven't seen any collisions on the few rectangles I've tried." :)

How to Conduct a Good C++ Phone Interview

January 1st, 2008

I've interviewed dozens of software engineers, mostly to fill positions involving C++. I've also interviewed for about a dozen positions involving C++ and lots of other technologies and languages. I thought I'd share some good on-the-phone interviewing techniques for the interviewer for C++ positions.

Before you read this, you shoud know that my interviewing technique is mostly inspired by Joel Spolsky's Guerilla Guide to Interviewing, which is a great read, though a little extreme for hiring programmers.

These questions usually take between 30 and 45 minutes to ask. A great candidate will answer all these and more in less than 30 minutes. A poor candidate will only get through half of them in 45 minutes. I've divided each question into sections. Some questions are not a single question per se, but more of a discussion topic. Enjoy!

Removing Duplicates from a List

The first thing I ask candidates is how to remove duplicates from a list. There are basically three answers to this question, and I want the candidate to give me all three, with the advantages and trade-offs of each. If they can only get two of them, I might hint them along to the third. If they still can't get the third answer, I almost never hire them.

The great candidate will ask me lots of questions up front, like what my data structure is. Is it a linked list or an array? What's the penalty for removing an item from the structure? Does it have random access of elements? These are all great quesions. I usually let the candidate assume that indexing is O(1), and so is removing items from the list. Good candidates will ask if the list is sorted first or not. Are the elements hashable? Are the elements easy to compare to eachother? If the candidate dives right into the answer without asking any of these questions, I usually don't hire them. Here are the three answers I want to get from the candidate:

Answer 1: The dumb way (N2)

For each element in the list, scan the rest of the entire list and remove matching elements.

Advantages: Easy to implement. No extra memory required.

Disadvantages: It's O(N2) slow, and on large lists it'll take a long time.

If they skip this one, and go straight to answer #2, that's just fine (even preferable).

Answer 2: The adequate way (N log(N))

Sort the list first. For each element in the list, look for duplicate neighbors only and remove them.

Advantages: Faster than Answer 1 because you don't have to iterate over the entire list for each element. No extra memory required. Pretty easy to implement.

Disadvantages: It's pretty good in most cases, but still not the (theoretical) fastest way.

Answer 3: Hash the elements

For each element in the list, insert it into a set structure that uses a hashing algorithm. When done, just pull out the values, and that's your unique list.

Advantages: Very fast (theoretically), on the order of O(N).

Disadvantages: You may choose a poor hashing algorithm and end up with a much worse speed. Implementing a reliable hashing algorithm can be hard, so you'll have to find one (like the non-standard hash_set class). It also uses much more memory than the other two answers (bonus: What is the memory complexity of this implementation).

As you can see, this question is not about "right or wrong", it's about how many solutions they can come up with, and whether they are able to adequately weigh their chosen solutions. This tells you a lot about a candidate. Note also that this is not strictly a C++ question.

Counting the Bits in a Byte that are One

In this question we want to see if they understand the C/C++ bit-wise operators. This may not be important if your position doesn't do a lot of bit twiddling, but it is for my job, so I always ask it. There are several ways to answer this question, again, so I'm seeing how far they'll take it. Again, I want good questions, like how much memory is available to them and whether performance is important.

Answer 1: Mask, compare, shift, mask, compare, shift, repeat

In this answer, you "and" the byte with one, and compare the result with one, then shift right by one bit, and repeat it seven more times, like this:

    unsigned char input = (some value);
    int count = 0;
    if (input & 1) count++;
    input >>= 1;
    if (input & 1) count++;
    input >>= 1;
    if (input & 1) count++;
    input >>= 1;
    ...

Of course, they could just use a loop like this:

    unsigned char input = (some value);
    int count = 0;
    for (int i=0; i<8; i++) {
        if (input & 1) count++;
        input >>= 1;
    }

I've seen some fun variations on this, like using the modulus operator (%) and the divide operator (/) instead of shifting and masking. Basically, in this case you are checking for "oddness" of the input byte and dividing by 2 each time (which is the same as right-shifting), like this:

    unsigned char input = (some value);
    int count = 0;
    for (int i=0; i<8; i++) {
        if (input % 2 == 1) count++;
        input /= 2;
    }

That's a fun one, and shows that, even though the candidate may not know the bit-wise operators well, at least he can improvise. We hired a candidate who gave this answer about a year ago. He told me on the phone that he didn't know the bit-wise operators, so I thought for sure that he wouldn't get the right answer, but he did! He turned out to be an awesome employee too (yes, Chris, I'm talking about you). :)

Answer 2: Short-circuited version of the above

You can modify the above to not iterate all 8 times, if not necessary, by changing the "for" loop to a "while" loop, like this:

    while (input) {
        ...

That way, it'll bail out as soon as the input hits 0 (which it will eventually), and it may happen sooner than 8 iterations. Actually, it'll happen that way more than half of the time. Ask the candidate in what cases would this save you a step (answer: it'll iterate at most 7 times for inputs less than 128, 6 times for inputs less than 64, 5 times for inputs less than 32, and so on).

Answer 3: Lookup Table

This is the fastest implementation to count bits, but it requires a pre-initialized array with 256 entries in it. It goes like this:

unsigned char input = (some value);
static int table[256] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, ..., 6, 6, 7, 7, 8 };
int count = table[(int)input];

The table takes byte values as inputs and returns the number of bits that are set in the byte. It must be pre-computed and statically-initialized to be fast. This works well because a byte can only have one of 256 values. If they can't get this answer, I will often hint them to it by asking, first, "Can you think of a faster solution if you have some memory available to you?" If they can't get it with that hint, I'll ask, "Can you think of a table-driven approach?". If they can't get it with those hints, I usually don't hire them. If they do really well on the rest of the questions, I may still hire them.

After they give this answer, you'll want to ask them about statically initialized data. They should understand that it's basically free to initialize. They should also know that if they don't statically declare that table, there will be a significant performance penalty.

Object Oriented

To get a feel for the candidate's understanding of object oriented programming, I like to ask them what polymorphism is. They usually come up with an example (the zoo, shapes, or cars usually). They talk about how having a common "Animal" base class is good because all Animal-derived classes can share data. This is a good answer, but the better answer is that a common ZooManager could treat all Animal-derived classes exactly the same, without having to know about each individual child class (Monkey, Elephant, etc).

I follow this question up with a question about C++'s "virtual" keyword, and what it means when a class member function is declared as virtual in, say, the Animal class previously mentioned. Candidates tend to get this one right about 50% of the time.

When a candidate is really good, we can get into a discussion about C++ multiple inheritance and the "unfavorable diamond" problem, and how to solve it with virtual inheritance. I've only had three candidates get that far with this question, and in all three cases, we hired them.

Understanding Networking

First I ask the candidate if they have any network programming experience. Bare in mind that most of our candidates have less than 5 years of experience. If they do have networking experience, I ask them the difference between TCP and UDP. I also ask them the difference between blocking and non-blocking network I/O.

Threading

First let me just say that I am astounded how few candidates have any multi-threaded programming experience. I am blown away by it. If the candidate has any threading experience, I ask them what a mutex is, what a semaphore is, and what deadlock is. I then ask them to give an example of a producer/consumer problem.

I also ask what the difference is between a thread and a process. If they come up short, I ask them follow-on questions like whether processes share memory, and whether threads share memory. Then I take it further, and ask if processes share heap or stack and if threads share heap or stack.

GUIs

If the candidate has any GUI-programming experience, I ask them why polymorphism is useful to GUIs. Usually they say something about how widgets (a.k.a. controls) can share common data like size and position. That is about 25% of the answer. That's just data sharing. The real answer is that the GUI's layout and event-dispatching code can treat all widgets identically. This means that widgets can re-implement specific functionality and the event-dispatcher (a.k.a, the event loop) can treat them all the same, even user-invented widgets. Widget-specific code, like painting, can be delegated to each widget without the rest of the toolkit having to know about it. The way Qt does this for example, is that there is a common QObject base-class, and a common QWidget class that inherits from it. QObjects can emit signals that can be connected to other QObject slots. QWidgets have an API for painting, sizing, etc., and can be sub-classed by users. Qt can treat these custom classes just like it does all the built-in QWidgets.

If they seem to have any significant GUI experience, I will ask them to send me screenshots of their work. I don't require anything spectacular (we'll teach them that on the job), but I do want to know if they have done anything beyond your basic CRUD application. I seriously don't care if someone has developed GUIs that even a computer could create. Show me something cool!

I also ask them what an event loop is, and what it does. I have yet to get a good answer to this one. If they do have a good answer, that usually means they are a great GUI programmer. If they don't, that just means they aren't great yet. :)

Embedded

If the candidate has any embedded programming experience, I ask them what an interrupt is and what the "volatile" keyword does in C. If they have any idea about either of them, it usually means that they actually did some embedded programming.

Well, that's pretty much it. Not too tricky and not too long. I can usually figure out whether to bring in a candidate for in-person interviews based on these questions alone. In some cases, I need to do some more work to get a better feel. For really excellent candidates, I can tell after their answer to the first question. About 90% of the time, when I bring in a candidate after passing this phone interview, they end up passing the rest of the in-person interviews.

I hope you find this information useful!

You’ve Been Commented

December 16th, 2007

Classic! Xkcd brings us the programmer's version of "talk to the hand":

Commenting someone in Perl or Python requires two hands.