A long time ago, I was asked to perform a programming function (FizzBuzz) on a whiteboard during an interview with T-SQL. I was able to get the theory behind it, but I am pretty poor at memorizing syntax. I’d rather spend my time studying concepts, theory, and technology. Indexes and cursors are two great examples. I don’t think it really matters if you don’t memorize how to write those by hand, it’s more valuable to understand how they work instead.
It takes about 30 seconds to google the syntax for a command but it can take hours of reading to understand how the command truly works. This is why I’m not a proponent of whiteboarding problems unless the person can have access to the internet for simple lookups. The goal behind the whiteboarding should be to see the thinking process of the individual and how they work through problems, not to “stump the chump”.
Likewise, I think it’s fine to have the interviewee read code or to give them word problems and ask for their interpretation. Points on syntax shouldn’t be accounted for unless you are a shop that just needs code monkeys to churn out basic code all day.
Let’s use the FizzBuzz example to explain how whiteboarding should go in an interview.
Write in the programming language that you want, a program that displays on screen the numbers from 1 to 100, replacing the multiples of 3 by the word “Fizz” and, in turn, the multiples of 5 by the word “Buzz”. For the numbers that, in time, are multiples of 3 and 5, use the word “FizzBuzz”.
FizzBuzz
One method to solve this is by creating a loop that increments and divides the value by 3 and 5 to test for a whole quotient number. Whole numbers are printed, while numbers that have a decimal are caught in the divide by 3, 5, or 3 and 5 filter. The key concepts here are order of operations, problem-solving, understanding of basic T-SQL, and basic math skills.
We start with dividing the value by both 3 and 5 because the CASE WHEN command evaluates the values sequentially and stops evaluating the condition as soon as it is met. Dividing by 3 and 5 will have commonalities with dividing by just 3 or 5, this is why we start by dividing with both. Afterward, we divide the remaining values by either 3 or 5. The order for which of those we divide by after testing both conditions is not relevant since there will be no commonalities. Through elimination, we know that all remaining numbers not divisible by 3 and 5, 3, or 5, are fine to print. So we print the value at the end of the CASE WHEN statement.
Here is a loop example of solving FizzBuzz:
DECLARE @Value DECIMAL(25, 2); SET @Value = 1; WHILE(@Value) <= 100 BEGIN IF ( SELECT CHARINDEX('.', (CAST(@Value AS FLOAT)/5)) ) = 0 AND ( SELECT CHARINDEX('.', (CAST(@Value AS FLOAT)/3)) ) = 0 BEGIN PRINT 'FizzBuzz'; END; ELSE BEGIN IF ( SELECT CHARINDEX('.', (CAST(@Value AS FLOAT)/3)) ) = 0 BEGIN PRINT 'Fizz'; END; ELSE BEGIN IF ( SELECT CHARINDEX('.', (CAST(@Value AS FLOAT)/5)) ) = 0 BEGIN PRINT 'Buzz'; END; ELSE BEGIN PRINT CAST(@Value AS SMALLINT); END; END; END; SET @Value = @Value + 1; END;
This isn't a very efficient approach however, let's find another way to speed this up:
DECLARE @FizzBuzz TABLE([ID] DECIMAL(25, 2)); DECLARE @Increment SMALLINT; SET @Increment = 1; WHILE(@Increment) <= 100 BEGIN INSERT INTO @FizzBuzz ( [ID] ) VALUES (@Increment); SET @Increment = @Increment + 1; END; SELECT CASE WHEN(CHARINDEX('.', (CAST([ID] AS FLOAT)/5))) = 0 AND (CHARINDEX('.', (CAST([ID] AS FLOAT)/3))) = 0 THEN 'FizzBuzz' WHEN(CHARINDEX('.', (CAST([ID] AS FLOAT)/3))) = 0 THEN 'Fizz' WHEN(CHARINDEX('.', (CAST([ID] AS FLOAT)/5))) = 0 THEN 'Buzz' ELSE CAST(CAST([ID] AS SMALLINT) AS VARCHAR(10)) END AS [ID] FROM @FizzBuzz;
The difference here is that I'm mostly using SET logic. The while loop is row by agonizing row (RBAR), but the SELECT clause is based on SET theory. It reads the entire table and applies the logic to a single transaction rather than doing this transaction 100 times altogether for the 100 rows.
We could speed this up more if we had some tables (even system tables would work) to create a cartesian join to populate the table variable up to 100. There are also many more methods of solving this problem, which is what I would want to capture from the interviewee. I don't care if they have to use books online to set up their WHILE loop. I care that they can come up with various ways to solve the problem and know where to go to enhance the solution. I also care about if they are able to explain their solution and why it works. The ability to teach what you know illustrates how well you know that subject better than showing me you can memorize syntax.