Programmers and software developers must undergo a series of tests and trials during their interview process before they are judged worthy.  During a phone screen you typically get questions that test your basic knowledge of Windows, C# and .NET Framework, and if you pass that stage you are invited for an in-person interview.  During that interview, at least one person on the development team will ask you to go to the whiteboard and write some code.  Joel on Software has some pretty good guidelines on what sort of code a candidate will write.

It's a great technique for detecting if the person really is a coder/programmer and not a poser.  (Or, as one of my college professors once said, to weed out the Spicolis.)  Whenever my company is hiring someone, myself or someone on my team will make the candidate perform this coding exercise.

However, when I am the candidate, I look forward to whiteboard coding about as much as a trip to the dentist.  I actively dread the moment when someone says, go to the whiteboard and write some code.  I feel a certain pain in my mind, akin to that dreaded pinch when the dentist injects Novocain into my mouth.  When I arrive at the whiteboard, my mind goes blank.  My knees feel weak.  I feel as if I suddenly belong in the marketing group.  Only I'm not thin or attractive enough to work in marketing.

Therefore, to overcome this fear, I've started collecting all kinds of interview whiteboard coding examples, and will share them with you here.  Most of the code you will see here is not the code I wrote during my interview.  But even if the interview went well or it was a disaster, I went home and tried to write the code when I was more relaxed.

I review these examples before going into a new interview.  I don't memorize the code per se; I do remember the general pattern of the solution and stumble through it on the whiteboard.

I'll be writing several articles in the weeks ahead, but this post will keep an index of all whiteboard code, which will be written in C:

Interview Coding: Fibonacci sequence

Interview Coding: Reversing a Singly Linked List in C

Interview Coding: atoi, itoa in C

Interview Coding: Reverse a string in C

Writing a function that returns the nth number in a Fibonacci sequence can either be the easiest interview whiteboard question or the hardest.  If you're like me, your daily activities revolve around events, delegates, background threads, data grid views, custom controls, or reading about some new area of C# and .NET that you've never encountered before.  A strange sequence of numbers stuns you like a phaser on Star Trek.  Even worse, you've probably heard of Fibonacci during your days at the University or in other interviews, but you just can't recall what it is.

If you're unfamiliar with Fibonacci, the interviewer will usually prep you by giving you a list of the first few numbers:

0 1 1 2 3 5 8 13 21

The interviewer should explain the most obvious property of the Fibonacci sequence: each number is the sum of the previous two numbers, if N > 1.  1 is the sum of 0+1, 2 is the sum of 1+1, 3 is the sum of 2+1, etc.  There are other properties of the Fibonacci sequence, which you can read about on this Wikipedia article.

You will be asked to write a function that returns the result of Fib(n).  The Wikipedia article explains clearly, if N > 1, the Fibonacci result is F(n-1) + F(n-2).  If you see this, you can almost write the code, but it may not be explained to you in this fashion.  The interviewer may tell you that Fib(1) == 1, and Fib(5) == 5.  How can that be?  It's helpful to think of the Fibonacci sequence in an array, starting at index 0:

F0 F1 F2 F3 F4 F5 F6 F7 F8
0 1 1 2 3 5 8 13 21

 

Now you can see, ironically enough, that Fib(5) is 5, but there's a logical reason, it's at index 5.  Fib(4) doesn't equal 4, it equals 3, because it is the 4th (after 0) in the sequence.  Once you understand that, you can start to write the code:

int fib(int n)
{
    if (n <= 1)
        return n;

return fib(n-1) + fib(n-2);
}

This is the preferred way to write a Fibonacci function, because it uses recursion.  If N is 0 or 1, that value will be returned.  If N is greater than 1, the fib function calls itself recursively, not once, but twice, with the 2 previous numbers in the sequence, n-1 and n-2.  If you call this with N set to 2, then fib will call itself twice with fib(1) and fib(0), which will return 1 and 0, and the sum will be 1.  It works like this for any higher value as well.

The wrong approach would be to set the Fibonacci sequence in a pre-defined array, and going to the Nth index and returning the value there.  But the interviewer will point out that the sequence can go on infinitely and you could never set down all the values.

This is not a perfect function.  If the numbers are negative, a negative value is returned.  You can argue that there will be a buildup of recursive stack values (if N is 10000 the stack will be enormous), or that we are losing performance by making two recursive calls in one function.

Why is recursion the preferred method?  It makes the code simple and easy to understand.  If you look at the Fibonacci definition in the Wikipedia article, the code above resembles that pseudocode definition almost perfectly.  You've solved the problem in the fewest lines of code.  We always hope to hire programmers who can deliver elegant solutions to complex problems.

Crystal Image Toolkit 0.82 is ready to download.

Minor Enhancements:

CrystalImageItem: Added DisplayName property.

This property will be used by CrystalImageGridView when it draws the text for the image item.  The DisplayName is separate and distinct from the ImageName.  ImageName for CrystalFileCollector is the name of the image file "image.png" whereas DisplayName could be "image1".

If DisplayName is not set, it will default to the value in ImageName.

CrystalImageItem: SplitImagePath now sets DisplayName as well as ImageName, ImageLocation.

CrystalImageItem: ToString() method uses DisplayName instead of ImageName.

CrystalImageGridModel, added new methods to help skip CrystalGroupItem objects...

  1. FirstNonHeaderIndex:
        Finds the index of the first item in the model that is not a CrystalGroupItem.
  2. LastNonHeaderIndex:
        Finds the index of the last item in the model that is not a CrystalGroupItem.
  3. PrevNonHeaderIndex:
        Finds the index of the previous item in the model that is not a CrystalGroupItem.
  4. NextNonHeaderIndex:
        Finds the index of the next item in the model that is not a CrystalGroupItem.

CrystalImageGridView: ShowThumbnails property added.

Set this property to false if you do not want anything displayed in the image grid view.  Only the gradient background will be shown. Setting the property back to true displays the thumbnail images.

CrystalImageGridView: DrawImageTitle now uses CrystalImageItem's DisplayName property for the title text.

CrystalComicShowController: unpack-wait dialog now positioned within the main form.

CrystalComicShowControllerDemo: Enhanced to convert images in CBR/CBZ files to a size compatible for viewing on the Sony PSP.  Fixed crashing bugs and sorting bugs from previous release.

Bug Fixes:

CrystalFileCollector: Images that have the hidden file attribute are now skipped when CollectImages is executed.

CrystalFileCollector, CrystalMemoryZipCollector, CrystalRarCollector:
Initial sorting of list was incorrect.  The sorting of the list must be done before the list/group item is added to the model.

CrystalImageGridView, CrystalPictureShow, CrystalPictureShowController:
Critical bug fixes where the controls tried to display or scroll to image item objects that were actually CrystalGroupItem objects.  The above methods are used to avoid them when necessary.

CrystalPictureShowController: Bug fix in DisplayImage.  Operations on the main GUI thread (_imageForm) synchronized with an Invoke and code inside MethodInvoker.

CrystalThumbnailer: Store method creates thumbnail folder if it does not exist.

CrystalThumbnailer: GetThumbnailName method bug fix, forward slashes '/' converted to '\'.  This was found in zip/rar files.

Code Cleanup:

CrystalImageItem: protected fields now change to private.
To access these values in child classes, you have to use the Properties encapsulating these fields.

CrystalTools: Class is now static (and therefore, sealed). 

Redundant Exception handlers were removed in various classes. 

NOTE: Exception handling will be revised in a near-future release.
Currently the toolkit is eating the exceptions and logging them; they obviously need to be thrown back to other objects in many cases.

Download: Crystal Image Toolkit 0.82.  Totally free, open-source, C# .NET Framework 2.0 for Windows Forms, works with both Visual Studio 2005 and 2008.

Cory Doctorow's Little Brother in Sony PSP Image viewer

Here's a roundabout story about I've reinvigorated my Sony Playstation Portable, which would not have been possible without Cory Doctorow's excellent novel, Little Brother.

I've been flirting with the Amazon Kindle for months ever since it went on sale.  It's a cool device for a book lover.  Imagine being able to carry around tons of books everywhere you go.  Being able to download a book after reading a review in the Sunday newspaper.  It's fantastic...except for the limitations.  DRM on the books that you download isn't very cool.  I think what really galls me is that Amazon charges for downloading blogs (via RSS) when you can easily get them for free online.  Charging to email/convert documents to the Kindle device is another thing I cannot understand.  Combine all of these things with the high price of the Kindle and I just cannot make that purchase.

Which made me turn to my Sony Playstation Portable.  I've let this device languish for the past two years after I stopped commuting to San Francisco on BART.  In the back of my mind, I've had this idea that the PSP, with it's brilliant screen display and brightness controls, could be a great e-book reader.  After visiting Cory Doctorow's Little Brother download page, where he provides the novel in a variety of formats (under Creative Commons license), I finally decided to give it a try and see if one of those would work on the PSP.

The result is that none of them worked that well.  It's amazing that after being first sold in 2005 in North America, the Sony PSP still does not have an Adobe PDF Reader.  I found one that used to work, but apparently not on firmware 4.05.  I suppose I could have gotten that to work if I flashed the PSP with a hacked set of firmware, but I want to keep up with the official builds from Sony, as I have a Playstation 3 and want to use my PSP in conjunction with that. 

Next, I tried the HTML version of Little Brother, which I copied over to the PSP/COMMON folder and pointed the PSP's browser at that location.  The HTML version looked superb, the text was very readable, and you can increase/decrease the text size very easily.

However, there were some problems with reading books in HTML format on the PSP.  Paging/scrolling to see the next page is a pain, when you must use the arrow keys on the left hand side of the device.  If the entire book is in one HTML file, you cannot jump between chapters that easily.  When I stopped near Chapter 3, then the next time I started the PSP, I spent a long time scrolling down (using square button + down) to get to that section.  I read that some Sony ebook fans will break up novels into several HTML chunks and link the whole thing together in an index file.  Too much work for me!

PSP EBook Creator

A friend of mine suggested converting the document into a series of JPG files and using the Sony PSP Photo/Image viewer.  I was really dubious about this until I found the PSP EBook Creator on download.com.  What the heck, I decided to give it a shot.  The PSP E-book Creator takes a text file file as the input/source, parses it and creates a series of JPG images.  It gives you a number of options for formatting the text: you can choose the font that you want, the font color, the background color, etc.  It may take a while to determine the best font to read on the PSP screen, I've found that either Arial or Verdana works best for me.

The e-book creator parsed and split the Little Brother source text into 897 jpg files, which I copied over to the PSP's PHOTO folder, under a subfolder called LB.  When I turn on the PSP, I simply navigated to the Photo slot, select Memory Stick, select the LB folder, select page 1 and pressed X.  Voila, the first page appears and it's easily readable.  To go to the next page, you just press the right shoulder button on top of the PSP.  The PSP can easily be held in one hand with a finger resting on the next button to advance pages.  The left shoulder button allows you to go to the previous page.

Several things are great about this.  Little Brother took up about 40 mb on my Sony Memory stick, which is pretty small.  Having the book split up into X number of jpgs allows you to quickly find the last page you were on: just press the down arrow to scroll down quickly to page 222 or whatever.  The Sony PSP has a brightness control on the front that allows you to see the screen during the daytime or at night.  This is really convenient if you're reading in bed and don't want to disturb your partner with a bright screen--the lowest brightness level works perfectly in total darkness.  You have no idea how long I've searched for a solution to this problem! 

What are the disadvantages of this method?  There are two big ones.  You can't customize the text size dynamically, and the glassy Sony PSP screen is not readable outdoors in the sunlight, due to the glare bouncing off the screen.  I usually read indoors, so this is not a problem for me.

Unlike the Kindle, where finding/downloading books is a breeze, finding content to download and convert is a challenge, as not every author is as generous as Cory Doctorow.  But if you're used to downloading other media, you can find content to use with the PSP E-Book Creator, although usually the content will need to be converted to text.  You can look for books that are in RTF or HTML format and convert to text using a number of programs (Internet Explorer, Firefox, Microsoft Word, etc).  Books in PDF file format can also be converted to text.  You can also find books in the Microsoft Reader format (.LIT files), and use the free ABC Amber LIT Converter program to convert them.

I've got about a dozen books, many of them recent books that I purchased in hardback (plus all of Doctorow's other novels), on my Sony PSP.  I bought a SanDisk 4 GB memory stick for about $40 on Amazon to hold this content, along with 12 episodes of LOST and a number of comic books that I want to read on my next vacation.  With all this content available, playing games on the PSP seems like a bonus feature.

Little Brother is a very engaging book, I devoured it in a couple of days after getting on my PSP.  Little Brother is a young adult novel (although just as good for adults) about a high school kid named Marcus Yallow (aka w1n5t0n) in San Francisco. San Francisco is attacked by terrorists and the Department of Homeland Security swoops in and starts heavily monitoring all citizens. Marcus fights back against the DHS by hacking his Xbox with an operating system called "Paranoid Linux" and inspiring a group of young techno-geeks to help him out.  I highly recommend it.

Link: PSP E-Book Creator

Link: ABC Amber Lit Converter

Link: Cory Doctorow's Craphound

Link: Little Brother site

Download: Little Brother for Sony PSP (Image files, zipped).

Crystal Image Toolkit 0.81 is ready to download.

New Feature: Header group items are now part of CrystalCollector, CrystalImageGridModel, and CrystalImageGridView.  You can now assign a group of thumbnail images to a collapsible header.  To illustrate this, here’s a screenshot from the demo application “HeaderGroupItemDemo” which is included in the project:

HeaderGroupItem1

There are four header groups visible that you can see here (FF, Hulk, Iron Man, Spider-Man).  Each contains a set of thumbnails.  The arrow icon indicates the expanded state; you can replace this icon in the framework as I am just using a free icon here.  Likewise you can replace the folder icon to represent something unique about this group of images if you wish.  But what’s important to note here is that the header group can be collapsed/expanded by clicking on it:

HeaderGroupItemCollapsed

Here I’ve collapsed two of the header items and left the other ones open.  You can see I have CrystalImageItem objects selected in each of the header groups.

In the C# code, Header groups translates to a CrystalGroupItem object containing a List of CrystalImageItem objects.  Each object now has a Parent property so it knows the group that it belongs to.  The biggest change in the collector is that now every GridModel has at least one root header. In the default mode, for backward compatibility, the header item is not displayed (ShowHeaders is set to false in CrystalImageGridView). This may cause problems in older applications that use CrystalImageGridView and try to navigate to item 0 in the GridModel.  You will need to do a test, such as: "if (theImage is CrystalGroupItem)".  See InitInitialImageImp in CrystalPictureShowController.cs for how to deal with this situation.

CrystalCollector now has an additional abstract method that requires you to CollectImages on a CrystalGroupItem object.  CrystalFileCollector implements this method and creates a default root header for simplicity.  But if you want to explicitly create CrystalGroupItem objects and add them to the collector, you do it like this:

   1: CrystalGroupItem groupItem = new CrystalGroupItem();

   2: groupItem.ImageName = "Fantastic Four";

   3: groupItem.ImageLocation = "..\\..\\SampleImages\\Fantastic Four";

   4: // Optional: set a unique image icon for this group header item in the image grid.

   5: //groupItem.FullImage = my Image icon;

   6: _theCollector.CollectImages(groupItem);


This is a bit of an early release of the header group feature.  In the future, I will add additional style bits for the header text font, add a border state around the header item, perhaps add mouse over events for it.

There are several bug fixes to the toolkit, which is why I wanted to release it now, even though this feature is a bit early.  To see all the bug fixes, please read the release notes in the zip file.

Download: Crystal Image Toolkit 0.81.  Totally free, open-source, C# .NET Framework 2.0 for Windows Forms.

Crystal Image Toolkit 0.80 is ready to download

New Features:

  • CrystalImageGridView now has ZoomFactor: allows scaling of thumbnail images!
    See ZoomImageGrid demo and Crystal Picture Show Controller demo.
  • CrystalPictureTracker: Pan Window that works with CrystalPictureShow.
    See Crystal Picture Show Controller demo.
  • CrystalPictureShow: Hand cursors that allow the user to drag zoomed images around.
  • CrystalImageGridView now has a new rounded rect border style.  Check out the groovy red borders in the Picture Show Controller demo.
  • Crystal Toolkit now integrates log4net.  See CrystalLogger object.
    You can get even more debug logging by declaring CRYSTAL_DEBUG in project properties/build.

And now it's demo time, with Marvel comics pictures, of course:

CrystalImageGridView using ZoomFactor to scale thumbnails

CrystalImageGridView: ZoomFactor applied to zoom to a larger thumbnail image.  See my earlier article that explains how to set this up.  Changes were made to CrystalPictureShowController to add a second trackbar object to control thumbnail zooming. 

CrystalPictureTracker working with CrystalPictureBox

CrystalPictureTracker: Panning (controlling CrystalPictureBox) in separate window.  Tracker window appears when image is larger than client area.  You can close it, make it appear again by clicking on the Pan Window button.

Red rounded borders

CrystalImageGridView: Rounded borders on selected images.  There is now a property called BorderState that allows you to switch between these rounded borders and the old square frame.  Also, notice that in the split view mode, the CrystalPictureShowController hides the thumbnail trackbar and toolstrip objects auto-magically.   Thumbnail sizes in the split mode are fixed, whereas in the vertical orientation (with a sheet of thumbnails) they can be scaled.

This release comes in a ZIP file. Simply unzip the contents to your hard drive, navigate to the root Attilan folder, and double click on CrystalDemo.sln. This solution file contains the Crystal Toolkit plus demo programs. Just build the solution (which compiles the CrystalToolkit library first) and run the demo programs to see how they work. You can run the demo programs without building the source by clicking on "StartDemo.bat" in the root Attilan folder or CrystalDemoLauncher.exe in Attilan\bin.

Download: Crystal Image Toolkit 0.80.  Totally free, open-source, C# .NET Framework 2.0 for Windows Forms. 

I haven't posted any articles here for quite a while.  You might think I've given up on the Crystal Toolkit, but not yet!  I've been making various improvements, bug fixes, and enhancements.  It's slowly getting better.  Probably by the time I am done, Windows Forms will be dead!

Here's a big feature, coming very soon in Crystal Toolkit 0.80, that I've wanted for my own image viewing programs: zooming the thumbnail images that are contained within CrystalImageGridView.  Previously I was only able to allow users to set the CellSize property and that was it.  If you had a thumbnail image that was 300 x 300, you were stuck with that until you changed that property and had the internal grid recalculate itself.  It might have worked, but the images would all have to be re-thumbnailed at that new size, and a lot of time would be wasted.

   1: /// <summary>
   2: /// Sets up the Matrix object used for displaying the image.
   3: /// </summary>
   4: /// <param name="gfx">Graphics object used for drawing.</param>
   5: /// <param name="zoomScale">Scale used for matrix.</param>
   6: protected virtual void SetupMainImageMatrix(Graphics gfx, float zoomScale)
   7: {
   8:     gfx.ResetTransform();
   9:  
  10:     // Set up the transformation to handle zooming and panning.
  11:     Matrix mx = new Matrix();
  12:  
  13:     // Account for the scroll position.
  14:     mx.Translate(AutoScrollPosition.X, AutoScrollPosition.Y);
  15:  
  16:     // Account for the zoom factor.
  17:     mx.Scale(zoomScale, zoomScale);
  18:  
  19:     // Set the transform into the global transform for the specified Graphics context.
  20:     gfx.Transform = mx;
  21:  
  22:     // Set the interpolation mode.
  23:     gfx.InterpolationMode = _interpolationMode;
  24: }

To make thumbnail scaling work in the new release, I've taken some code and patterns found in CrystalPictureBox.  In that class, I used a Matrix object and set the scale according to a property I called ZoomFactor.  This enabled me to present an image in CrystalPictureBox at any scale I desired, like from 30% of full size to 300% of full size.

CrystalImageGridView now has a property called ZoomFactor.  Using this, the entire grid can be displayed at a percentage of the full sized grid.  To implement an image grid that goes from small images to medium images to large images, you would just set the ZoomFactor in the image grid, and the object takes care of the rest.

How it works:

Setting up CrystalImageGridView for large thumbnails

First, setup a Form and drop the CrystalImageGridView onto the form.  Set the CellSize property to the largest possible size that you wish to display.  In this case, I chose a cell size of 375 x 375.  If you set it up this way, the thumbnailer object (internal to the grid) will make thumbnail images at this size, providing users with a crisp view.  It's easier to downscale a larger image than it is to upscale a smaller image.  Now, an alternative way to do this could have been a different pattern--where we send out a signal that we are changing the size and thumbnail the viewable images on the spot.  Windows Explorer and several other programs do this.  Perhaps in the future I will provide an alternative method like this.  The advantage of this method is that the image scaling is pretty fast.  The disadvantage is that the thumbnailed image requires more disk space at the largest possible size.

   1: private float[] zoomFactor = { .30f, .45f, .60f, .75f, .90f, 1.0f };

The ZoomFactor property is set by a trackbar in my little example program (which will be in Crystal Toolkit 0.80).  The zoom factors are predefined in array.  At the lower end of the scale (represented by setting the trackbar all the way to the left) we have 30% of the full size 375x375, which is 125x125.  At the upper end, we have 100% of the thumbnail size.  There is a trackbar on the form with Minimum set to 0 and Maximum set to 5, to match the settings in the array.

CrystalImageGridView with ZoomFactor at 30% 

When the program is launched, the default ZoomFactor is set to 0.30 (125x125).  I've got about 24 thumbnails displaying here.  Notice how the text for the image is still visible at this 30% setting, this was actually the trickiest part of the whole deal (and there may be bugs left to find in that regard).  OK, I've got the Hulk selected in the middle of the screen, keep an eye on him.

CrystalImageGridView with ZoomFactor at 50%

Here the ZoomFactor is set close to 50%.  The grid has repositioned the images as the ZoomFactor increased in size.  The Hulk remains selected, in the center of the grid so that the user can view his beautiful face.  Is that a booger in his hose?  Let's zoom it up further.

CrystalImageGridView with ZoomFactor at 100%

Finally, here's what the CrystalImageGridView looks like with the ZoomFactor at 100% (375x375).  We've got two images side by side, the Hulk is still selected and viewable.  And it's not a booger, it's this wild Marvel character called Ant-Man, making a quick exit from the Hulk's gamma irradiated body.

With good luck, I should be posting Crystal Toolkit 0.80 with this feature this Memorial Day.  Nuff said.

Ever had one of those days when you spent fighting with your operating system when you should have been getting real work done? I just had one of them. My computer at home is much faster and better equipped to do development work than my work laptop. We use SVN for source code control. For SVN client access, we use SmartSVN from SyntEvo. After setting up our repository URL in the SmartSVN, I was able to browse our repository folder structure, and begin to check out a project. But after retrieving a few files, it would crap out with errors like "connection closed" or "svn: null".

When things like this go wrong, most people would just give up or go back to the laptop. But this is the sort of the thing that makes me crazy until I find out what the problem is. I had my laptop--which worked with the same SVN settings on my home network. The difference was the work laptop was Windows XP SP 2--and my home desktop computer was Windows Vista. A-ha! Windows Firewall? Turned it off, same thing. McAfee Virus Scan? Uninstalled it, same thing. DLink router? Disabled the firewall, allow network access, same thing.

Searched SmartSVN forums--no answer. Tried TortoiseSVN--same problem. Tried another product called Syncro SVN--again, same behavior. I'm falling further behind on my deadline, when I give up and write to our terrific IT captain from Ancient Geek that he was right--Vista sucks.

Luckily, I did, because he told me what the real problem was--the TCP/IP auto tuning feature that Vista has. According to this article at ChapterZero:

Microsoft Windows Vista has auto-tuning enabled for TCP/IP which continually adjusts itself. It increases file transfer speed on the network but in some cases it may actually slow down everything which is accessing network. Auto-tuning also slows down network browsing of other machines on the network.

It's easy to check and see what your current TCP/IP receive tuning level is. Open up a CMD window with admin priviliges and type:

netsh interface tcp show global

Then if it's on and you want to turn it off:

netsh interface tcp set global autotuning=disabled

More detailed steps are given for this at SpeedGuide.

No wonder I drove myself nuts. I kept searching and searching for anything network related in the Control Panel and it wasn't there. Now that I've disabled this feature, both SmartSVN and TortoiseSVN are working fine. Thank you, Ancient Geek!

Previous 1 2 3 4 5 6 Next