I recently started learning Scala because of its Actor Framework. Over the last few weeks, I've been working my way through the Programming in Scala book. Having done that, I figured I'd test myself out using some of Steve Yegge's Phone Screen Questions. I've had the opportunity to be on both sides of the interview table/phone with Steve's strategy, and both as interviewee and interviewer, I think the approach works much better than the others I have encountered/tried.

I've adapted the strategy somewhat for my own purposes. One, I hardly do any phone screens - almost all the interviews I've done over the past couple of years have been face-to-face. Two, I usually cover 3 areas instead of the 5 Steve advocates - our interviews last about 45 minutes, and 10-15 minutes per question leaves just enough time to answer questions that the candidate may have about us. To get maximum coverage, a few colleagues (who also follow this strategy) and I usually split up the areas amongst ourselves prior to the interview.

In any case, I've noticed that reading a programming language tutorial usually leaves me with just enough knowledge to read code in that language. Writing some code is the only way I actually get to a point where I can program in that language. So if you are like me, reading this post will probably not do you much good - except perhaps to notice the many similarities to Java. However, if you are one of the lucky few who are able to absorb a language by reading code, then this post contains some simple Scala code to implement the coding questions in Steve's page referenced above.

On the other hand, if you are an experienced Scala programmer, I am guessing that much of this code would look very primitive and/or Java-like to you. In that case, I would appreciate your feedback and hints/pointers on better ways to do things in Scala.

Maven Project Setup

The lift Project (a Scala web framework) provides a Maven2 archetype for basic Scala projects, so that you get all the Maven2 goodness and its associated productivity boost for free in your Scala project. To create a basic Scala project, run the command:

1 2 3 4 5 6 7 sujit@sirocco:~$ mvn archetype:create \ -DarchetypeGroupId=org.scala-tools.archetypes \ -DarchetypeArtifactId=scala-archetype-simple \ -DarchetypeVersion=1.2 \ -DremoteRepositories=http://scala-tools.org/repo-releases \ -DgroupId=com.mycompany.smi \ -DartifactId=scala-examples

Update the scala.version property in the generated POM to suit your setup (I am using Scala 2.7.3). I started out using the Scala Eclipse plugin, so I did mvn eclipse:eclipse to generate my Eclipse IDE descriptors. Then follow instructions on the plugin page to configure the plugin in your IDE.

However, (at least in my case, I was using Eclipse 3.4.1/MyEclipse 7/Scala 2.7.3 with the plugin available from the update site), the Eclipse plugin was so bad as to be almost unusable. There was no code-suggest, editors would freeze and would need to be closed and reopened, etc. I ended up using Netbeans Scala plugin (with Netbeans 6.5), and it is sooo much better. Netbeans also recognizes a Maven project natively, so no descriptors need to be generated. My only gripe with Netbeans is its tendency to randomly freeze up for 30-40s at a time, something I've never seen with Eclipse.

Anyway, here are Steve's questions (and some of my own) and my Scala solutions below.

Reverse a String

This is actually one of my favorites. But the nice thing about this one is that it is extendable in so many interesting ways. Here are some of mine.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 // Source: src/main/scala/com/mycompany/smi/coding/StringReverser.scala package com . mycompany . smi . coding object StringReverser { // calling the method on String directly def reverse1 ( s: String ): String = { s . reverse } // iterating backward through the string def reverse2 ( s: String ): String = { val buf = new StringBuilder val len = s . length for ( i <- 0 until len ) { buf . append ( s . charAt ( len - i - 1 )) } buf . toString } // recursively def reverse3 ( s: String ): String = { val len = s . length if ( len == 1 ) { s } else { reverse3 ( s . substring ( 1 , len )) + s . charAt ( 0 ) } } // recursively, another one def reverse4 ( s: String ): String = { val len = s . length if ( len == 1 ) { s } else { s . substring ( len - 1 , len ) + reverse4 ( s . substring ( 0 , len - 1 )) } } }

The rather long and verbose class (and object) names in my post is in keeping with Steve's post about Java being the Kingdom of Nouns, and because I guess I've worked too long with Spring :-).

The first answer is correct, but probably not quite what most interviewers are looking for. The second one is usually what I get from a majority of people, with minor variations (I like reading the string backwards when I do this in Java, for one). The third and fourth versions are almost always the result of asking if there are other ways to do the same thing. Here is the JUnit test harness to run this code.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 // Source: src/test/scala/com/mycompany/smi/coding/StringReverserTest.scala package com . mycompany . smi . coding import org.junit._ import org.junit.Assert._ @Test class StringReverserTest { @Test def testReverse1 () = { assertEquals ( "madA m'I madaM" , StringReverser . reverse1 ( "Madam I'm Adam" )) } @Test def testReverse2 () = { assertEquals ( "madA m'I madaM" , StringReverser . reverse2 ( "Madam I'm Adam" )) } @Test def testReverse3 () = { assertEquals ( "madA m'I madaM" , StringReverser . reverse3 ( "Madam I'm Adam" )) } @Test def testReverse4 () = { assertEquals ( "madA m'I madaM" , StringReverser . reverse4 ( "Madam I'm Adam" )) } }

Compute the n-th Fibonacci Number

The objective here is to compute the n-th Fibonacci number, where n is provided in the target method's parameter list. I provide two versions of a Fibonacci Number generator below. The recursive version is more intuitive, although someone may ask you do this using iteration, so its probably good to know.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 // Source: src/main/scala/com/mycompany/smi/coding/FibonacciGenerator.scala package com . mycompany . smi . coding object FibonacciGenerator { // iterative version def generate1 ( n: Int ): Int = { if ( n < 0 ) { throw new IllegalArgumentException ( "Invalid Argument, n must be >= 0" ) } if ( n == 0 ) 0 else if ( n == 1 ) 1 else { var prev2 = 0 var prev1 = 1 var sum = 0 for ( i <- 2 to n ) { sum = prev1 + prev2 prev2 = prev1 prev1 = sum } sum } } // recursive version def generate2 ( n: Int ): Int = { if ( n == 0 ) 0 else if ( n == 1 ) 1 else { generate2 ( n - 2 ) + generate2 ( n - 1 ) } } }

Notice that you are calling the same function with the same argument twice multiple times in the recursive version, so caching the results of the calls may result in some improvement in the algorithm. The JUnit test harness is shown below:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 // Source: src/test/scala/com/mycompany/smi/coding/FibonacciGeneratorTest.scala package com . mycompany . smi . coding import org.junit._ import org.junit.Assert._ class FibonacciGeneratorTest { val first8Fibs = List [ Int ] ( 0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 ) @Test def testGenerate1 () = { var results = List [ Int ]() for ( i <- 0 until 8 ) { results += FibonacciGenerator . generate1 ( i ) } assertEquals ( results , first8Fibs ) } @Test def testGenerate2 () = { var results = List [ Int ]() for ( i <- 0 until 8 ) { results += FibonacciGenerator . generate2 ( i ) } assertEquals ( results , first8Fibs ) } }

Print Multiplication Table of 12

The objective here is to print multiplication tables uptil the number provided. There are 4 implementations provided. The first three do exactly what is asked, in slightly different ways, and that is a good thing. The last one actually introduces complexity without any gain, and that was me pandering to the CS person in me, and hopefully I will not get my head cut off for it :-). Actually, I wanted to play with classes, and populating and printing a 2 dimensional array seemed to be a good idea to be able to do that.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 // Source: src/main/scala/com/mycompany/smi/coding/MultiplicationTableGenerator.scala package com . mycompany . smi . coding import org.apache.commons.lang._ object MultiplicationTableGenerator { // just print it out in rows and columns, no formatting def generate1 ( n: Int ): Unit = { for ( i <- 1 to n ) { for ( j <- 1 to n ) { print ( " " + ( i * j )) } println } } // print with formatting def generate2 ( n: Int ): Unit = { val maxwidth = String . valueOf ( n * n ). length for ( i <- 1 to n ) { for ( j <- 1 to n ) { print ( " " + lpad ( String . valueOf ( i * j ), maxwidth )) } println } } def lpad ( s: String , width: Int ): String = { val maxpad = " " * width val maxpadded = maxpad + s val maxlen = maxpadded . length maxpadded . substring ( maxlen - width , maxlen ) } // use StringUtils.lpad for formatting def generate4 ( n: Int ): Unit = { val maxwidth = String . valueOf ( n * n ). length for ( i <- 1 until n ) { for ( j <- 1 until n ) { print ( StringUtils . leftPad ( String . valueOf ( i , j ), maxwidth )) } println } } // store and print def generate4 ( n: Int ): Unit = { printFormatted ( build ( 12 )) } private def build ( n: Int ): Matrix [ Int ] = { var matrix = new Matrix [ Int ]( n , n ) for ( i <- 0 until n ) { for ( j <- 0 until n ) { matrix . set ( i , j , (( i + 1 ) * ( j + 1 ))) } } matrix } private def printFormatted ( matrix: Matrix [ Int ]): Unit = { val maxwidth = String . valueOf ( matrix . rows * matrix . cols ). length for ( i <- 0 until matrix . rows ) { for ( j <- 0 until matrix . cols ) { print ( " " + lpad ( String . valueOf ( matrix . get ( i , j )), maxwidth )) } println } } } // only used for generate4() class Matrix [ T ]( nrows: Int , ncols: Int ) { val rows = nrows val cols = ncols private var elements = new Array [ T ]( rows * cols ) def set ( x: Int , y: Int , value: T ): Unit = { if (( x < cols ) && ( y < rows )) { elements (( y * cols ) + x ) = value } else { throw new IllegalArgumentException ( "(" + x + "," + y + ") should be in range (0,0) to (" + cols + "," + rows + ")" ) } } def get ( x: Int , y: Int ): T = { if (( x < cols ) && ( y < rows )) { elements (( y * cols ) + x ) } else { throw new IllegalArgumentException ( "(" + x + "," + y + ") should be in range (0,0) to (" + cols + "," + rows + ")" ) } } }

The JUnit test is similar to the ones shown already, and is shown below. The only difference is that it doesn't do asserts.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 // Source: src/test/scala/com/mycompany/smi/coding/MultiplicationTableGeneratorTest.scala package com . mycompany . smi . coding import org.junit._ import org.junit.Assert._ class MultiplicationTableGeneratorTest { @Test def testGenerate1 () = { println ( ">> generate1" ) MultiplicationTableGenerator . generate1 ( 12 ) } @Test def testGenerate2 () = { println ( ">> generate2" ) MultiplicationTableGenerator . generate2 ( 12 ) } @Test def testGenerate3 () = { println ( ">> generate3" ) MultiplicationTableGenerator . generate3 ( 12 ) } @Test def testGenerate4 () = { println ( ">> generate4" ) MultiplicationTableGenerator . generate4 ( 12 ) } }

Sum up Integers from Text File

The objective here is to read a text file of numbers, one number to a line, and print out the sum of these numbers. There are two implementations of this solution, the first one does it the Java way (with looping), and the second one does it the Scala way (with a foreach over a List. I also have a method to return an Iterator of lines given a file name (which is reused in some related questions, see below).

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 // Source: src/main/scala/com/mycompany/smi/coding/FileOperator.scala package com . mycompany . smi . coding import scala.io._ import scala.collection.mutable.Map import scala.collection.mutable.LinkedHashMap object FileOperator { // the java way def computeSumOfValues1 ( file: String ): Int = { var sum = 0 var lno = 0 for ( line <- lines ( file )) { lno = lno + 1 try { sum += Integer . parseInt ( chomp ( line )) } catch { case ex: NumberFormatException => { println ( "ERROR on line " + lno + ", " + chomp ( line ) + " not number" ) } } } sum } // the scala way def computeSumOfValues2 ( file: String ): Int = { var sum = 0 lines ( file ) foreach ( sum += toNumber ( _ )) sum } private def lines ( file: String ): Iterator [ String ] = { Source . fromFile ( file ). getLines } private def toNumber ( s: String ): Int = { try { Integer . parseInt ( chomp ( s )) } catch { case ex: NumberFormatException => 0 } } // maybe just simpler to use StringUtils.chomp() private def chomp ( s: String ): String = { try { if (( s . charAt ( s . length - 1 ) == '

' ) || ( s . charAt ( s . length - 1 ) == '\r' )) { s . substring ( 0 , s . length - 1 ) } else if ( s . substring ( s . length - 2 , s . length ) == "\r

" ) { s . substring ( 0 , s . length - 2 ) } else { s } } catch { case ex: StringIndexOutOfBoundsException => s } } ... }

One thing to note that you should not call any of your application packages java or scala. Because of the way Scala namespaces work, IDEs (and possibly the scala compiler) will get confused about which namespace you are importing from. I initially had com.mycompany.scala as part of my package name, but changed it to com.mycompany.smi in response to the problem described above.

Here are a couple of my own questions. I try and ask different questions from whats on Steve's list, just because, although I am guessing someone who reads Steve's post is probably capable of solving problems of similar complexity.

Compute Word Frequency from Text File

The objective here is to find the word frequency for a given file full of words. The output is a Map of words and their frequencies. As before, the first implementation is in the Java style, and the second one is in the Scala style. The second implementation uses two nested generators with a predicate on the second generator. These two functions are part of the same FileOperator object for the last question.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 // Source: src/main/scala/com/mycompany/smi/coding/FileOperator.scala // (cont'd) ... object FileOperator { ... def computeWordFrequencyMap1 ( file: String ): Map [ String , Int ] = { var wordcounts = Map . empty [ String , Int ] for ( line <- lines ( file )) { val words = line . split ( "[ ,;.!?-]+" ) for ( word <- words ) { if ( word . trim . length > 0 ) { addWord ( chomp ( word ), wordcounts ) } } } wordcounts } // multiple generators version def computeWordFrequencyMap2 ( file: String ): Map [ String , Int ] = { var wordcounts = Map . empty [ String , Int ] for ( line <- lines ( file ); word <- line . split ( "[ ,;.!?]+" ) if ( word . trim . length > 0 )) { addWord ( chomp ( word ), wordcounts ) } wordcounts } // refactored out to make the second version easier to write def addWord ( word: String , map: Map [ String , Int ]): Unit = { val origCount = if ( map . contains ( word )) map ( word ) else 0 map + ( word -> ( origCount + 1 )) } ... }

Sort a Map[String,Int] by Value

Now that we have a Map of word frequencies, we want to know the highest occuring words, so that involves sorting the Map by its value. The code below uses a Scala style comparator function in the keys.sort() call.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 // Source: src/main/scala/com/mycompany/smi/coding/FileOperator.scala // (cont'd) ... object FileOperator { ... def sortByValue ( unsorted: Map [ String , Int ]): Map [ String , Int ] = { val sortedMap = new LinkedHashMap [ String , Int ]() val keys = unsorted . keys . toList // sort in descending order of value val sortedKeys = keys . sort (( a , b ) => { unsorted ( a ) > unsorted ( b )}) sortedKeys . foreach ( key => sortedMap + ( key -> ( unsorted ( key )))) sortedMap } }

The JUnit test for the last 3 questions (in FileOperator) are shown below. It uses two test data files, test1.txt, which contains integers, one per line, and test2.txt, which contains free form text spread across multiple lines.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 // Source: src/main/scala/com/mycompany/smi/coding/FileOperatorTest.scala package com . mycompany . smi . coding import org.junit._ import org.junit.Assert._ class FileOperatorTest { @Test def testComputeSumOfValues1 () = { println ( ">> sumOfValues1 [test1.txt]" ) val sum = FileOperator . computeSumOfValues1 ( "src/test/resources/test1.txt" ) println ( sum ) assertEquals ( 2667 , sum ) } @Test def testComputeSumOfValues2 () = { println ( ">> sumOfValues2 [test1.txt]" ) val sum = FileOperator . computeSumOfValues2 ( "src/test/resources/test1.txt" ) println ( sum ) assertEquals ( 2667 , sum ) } @Test def testComputeWordFrequencyMap1 () = { println ( ">> wordFrequencyMap1 [test2.txt]" ) val map = FileOperator . computeWordFrequencyMap1 ( "src/test/resources/test2.txt" ) println ( map ) assertEquals ( 2 , map ( "morning" )) assertEquals ( 1 , map ( "breakfast" )) } @Test def testComputeWordFrequencyMap2 () = { println ( ">> wordFrequencyMap2 [test2.txt]" ) val map = FileOperator . computeWordFrequencyMap2 ( "src/test/resources/test2.txt" ) println ( map ) assertEquals ( 2 , map ( "morning" )) assertEquals ( 1 , map ( "breakfast" )) } @Test def testSortByValue () = { println ( ">> sortByValue" ) val sortedMap = FileOperator . sortByValue ( FileOperator . computeWordFrequencyMap2 ( "src/test/resources/test2.txt" )) println ( sortedMap ) } }

Print out Odd Numbers from 1-99

The objective is pretty clear from the heading. The next 3 questions have single implementations each, mostly focusing on (what I believe are) the Scala way of doing things. They are all contained in a single file Misc.scala, relevant portions of which are split up among the next three sections.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 // Source: src/main/scala/com/mycompany/smi/coding/Misc.scala package com . mycompany . smi . coding import java.util.Random import org.apache.commons.lang.StringUtils object Misc { def printOdds ( min: Int , max: Int ): List [ Int ] = { val range = new Range ( min , max , 1 ) range . toList filter ( _ % 2 == 1 ) } ... }

Find largest int value in an int array

Given an int array (our method actually populates it first using java.util.Random), find the maximum value in the array.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // Source: src/main/scala/com/mycompany/smi/coding/Misc.scala ... object Misc { ... def max ( n: Int ): Int = { // populate val randomizer = new Random ( n ) var arr = new Array [ Int ]( n ) for ( i <- 0 until n ) { arr ( i ) = randomizer . nextInt ( n ) } println ( ">> input: " + arr . toList ) // find max in list var max = 0 arr . foreach ( elem => if ( max < elem ) max = elem else max = max ) max } ... }

Format RGB value as a 6 digit Hex String

The objective here is to return a hexadecimal RGB string given three bytes representing the R, G, and B portions of a color. The approach here is not Scala specific, a Java version of this would probably look quite similar.

1 2 3 4 5 6 7 8 9 10 // Source: src/main/scala/com/mycompany/smi/coding/Misc.scala ... object Misc { ... def toHexString ( r: Byte , g: Byte , b: Byte ): String = { val rgb = ( r << 16 ) + ( g << 8 ) + b "0x" + StringUtils . leftPad ( Integer . toHexString ( rgb ), 6 , '0' ) } }

And here is the JUnit test for the 3 methods described above.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 // Source: src/test/scala/com/mycompany/smi/coding/MiscTest.scala package com . mycompany . smi . coding import org.junit._ import org.junit.Assert._ class MiscTest { @Test def testPrintOdds () = { println ( ">> printOdds" ) println ( Misc . printOdds ( 0 , 99 )) } @Test def testMax () = { println ( ">> max" ) println ( Misc . max ( 10 )) } @Test def testToHexString () = { println ( ">> toHexString" ) println ( "RGB(0x00, 0x00, 0x00)=" + Misc . toHexString ( 0x00 , 0x00 , 0x00 )) println ( "RGB(0x11, 0x11, 0x11)=" + Misc . toHexString ( 0x11 , 0x11 , 0x11 )) println ( "RGB(0x11, 0x00, 0x00)=" + Misc . toHexString ( 0x11 , 0x00 , 0x00 )) println ( "RGB(0x00, 0x11, 0x00)=" + Misc . toHexString ( 0x00 , 0x11 , 0x00 )) println ( "RGB(0x00, 0x00, 0x11)=" + Misc . toHexString ( 0x00 , 0x00 , 0x11 )) println ( "RGB(0x11, 0x00, 0x11)=" + Misc . toHexString ( 0x11 , 0x00 , 0x11 )) } }

My take after going this far with Scala is that for an average Java programmer such as myself, learning to use Scala seems to be fairly simple. The map, foreach, etc. methods seem intuitive, but hard to grasp and to apply correctly at first, but become easier with repeated usage. There are also some aspects, such as discussions on currying, covariance, contravariance, etc, that I haven't fully gotten as yet, but hopefully they will also be understandable as I work more with Scala.